home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Text Editor / Source / TextEditorEvents.cpp < prev    next >
Encoding:
Text File  |  1995-12-13  |  76.3 KB  |  2,939 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2.  
  3.     File:            TextEditorEvents.cpp
  4.     
  5.     Description:    TextEditor's event handling protocol methods.
  6.         
  7.     Written by:        Steve Smith
  8.     
  9.     Copyright:        © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  10.     
  11. ------------------------------------------------------------------------------*/
  12.  
  13. // Notification that this is a SOM source file
  14. #define SampleCode_TextEditor_Class_Prototypes
  15. // define underscore (_) field names
  16. #define VARIABLE_MACROS
  17.  
  18. #ifndef _COMPILERDEFS_
  19. #include "CompDefs.h"
  20. #endif
  21.  
  22. // -- OpenDoc Utilities --
  23.  
  24. #ifndef _EXCEPT_
  25. // Exceptions define several important macros (e.g. CHECKENV)
  26. // which are used in the SOM method dispatch glue. If Except.h
  27. // is not included early enough, exceptions may not be thrown
  28. // correctly when returning from a SOM method with "ev" parameter set.
  29. #include <Except.h>
  30. #endif
  31.  
  32. // -- TextEditor Includes
  33.  
  34. #ifndef SOM_SampleCode_TextEditor_xih
  35. #include "TextEditor.xih"
  36. #endif
  37.  
  38. #ifndef _TEXTEDITORDEF_
  39. #include "TextEditorDef.h"
  40. #endif
  41.  
  42. #ifndef _TEXTEDITORUTILS_
  43. #include "TextEditorUtils.h"
  44. #endif
  45.  
  46. #ifndef _TEXTEDITORGLOBALS_
  47. #include "TextEditorGlobals.h"
  48. #endif
  49.  
  50. #ifndef _TEXTEDITORPREFS_
  51. #include "TextEditorPrefs.h"
  52. #endif
  53.  
  54. #ifndef _TEXTEDITORSETTINGS_
  55. #include "TextEditorSettings.h"
  56. #endif
  57.  
  58. #ifndef _STDTEXTPROPERTIES_
  59. #include "StdTextProps.h"
  60. #endif
  61.  
  62. // -- OpenDoc Includes --
  63.  
  64. #ifndef _ODTYPES_
  65. #include <ODTypes.h>
  66. #endif
  67.  
  68. #ifndef SOM_ODCanvas_xh
  69. #include <Canvas.xh>
  70. #endif
  71.  
  72. #ifndef SOM_ODPart_xh
  73. #include <Part.xh>
  74. #endif
  75.  
  76. #ifndef SOM_ODStorageUnit_xh
  77. #include <StorageU.xh>
  78. #endif
  79.  
  80. #ifndef SOM_ODSession_xh
  81. #include <ODSessn.xh>
  82. #endif
  83.  
  84. #ifndef SOM_ODArbitrator_xh
  85. #include <Arbitrat.xh>
  86. #endif
  87.  
  88. #ifndef SOM_ODFocusSet_xh
  89. #include <FocusSet.xh>
  90. #endif
  91.  
  92. #ifndef SOM_Module_OpenDoc_Foci_defined
  93. #include <Foci.xh>
  94. #endif
  95.  
  96. #ifndef SOM_ODMenuBar_xh
  97. #include <MenuBar.xh>
  98. #endif
  99.  
  100. #ifndef SOM_ODClipboard_xh
  101. #include <Clipbd.xh>
  102. #endif
  103.  
  104. #ifndef SOM_ODFacet_xh
  105. #include <Facet.xh>
  106. #endif
  107.  
  108. #ifndef SOM_ODFrameFacetIterator_xh
  109. #include <FrFaItr.xh>
  110. #endif
  111.  
  112. #ifndef SOM_ODFrame_xh
  113. #include <Frame.xh>
  114. #endif
  115.  
  116. #ifndef SOM_ODDragAndDrop_xh
  117. #include <DragDrp.xh>
  118. #endif
  119.  
  120. #ifndef SOM_ODDragItemIterator_xh
  121. #include <DgItmIt.xh>
  122. #endif
  123.  
  124. #ifndef SOM_ODShape_xh
  125. #include <Shape.xh>
  126. #endif
  127.  
  128. #ifndef SOM_Module_OpenDoc_Commands_defined
  129. #include <CmdDefs.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODTranslation_h
  133. #include <Translt.xh>
  134. #endif
  135.  
  136. #ifndef SOM_ODWindowState_xh
  137. #include <WinStat.xh>
  138. #endif
  139.  
  140. // -- OpenDoc Utilities --
  141.  
  142. #ifndef _FOCUSLIB_
  143. #include <FocusLib.h>
  144. #endif
  145.  
  146. #ifndef _BARRAY_
  147. #include <BArray.h>
  148. #endif
  149.  
  150. #ifndef _DLOGUTIL_
  151. #include <DlogUtil.h>
  152. #endif
  153.  
  154. #ifndef _PLFMDEF_
  155. #include <PlfmDef.h>
  156. #endif
  157.  
  158. #ifndef _ODUTILS_
  159. #include <ODUtils.h>
  160. #endif
  161.  
  162. #ifndef _TEMPOBJ_
  163. #include <TempObj.h>
  164. #endif
  165.  
  166. #ifndef _USERSRCM_
  167. #include <UseRsrcM.h>
  168. #endif
  169.  
  170. // -- Macintosh Includes --
  171.  
  172. #ifndef __ERRORS__
  173. #include <Errors.h>
  174. #endif
  175.  
  176. #ifndef __EVENTS__
  177. #include <Events.h>
  178. #endif
  179.  
  180. #ifndef __DRAG__
  181. #include <Drag.h>
  182. #endif
  183.  
  184. #ifndef __RESOURCES__
  185. #include <Resources.h>
  186. #endif
  187.  
  188. #ifndef __QUICKDRAW__
  189. #include <Quickdraw.h>
  190. #endif
  191.  
  192. // -- Textension Includes --
  193.  
  194. #ifndef _Textension_
  195. #include "Textension.h"
  196. #endif
  197.  
  198. #ifndef _TSMTextension_
  199. #include "TSMTextension.h"
  200. #endif
  201.  
  202. #ifndef _QDTextRun_
  203. #include "QDTextRun.h"
  204. #endif
  205.  
  206. #ifndef _Display_
  207. #include "Display.h"
  208. #endif
  209.  
  210. #ifndef _AdvancedRuler_
  211. #include "AdvancedRuler.h"
  212. #endif
  213.  
  214. #ifndef _RunObject_
  215. #include "RunObject.h"
  216. #endif
  217.  
  218. #ifndef _LinkedFrames_
  219. #include "LinkedFrames.h"
  220. #endif
  221.  
  222. #ifndef _AttrObject_
  223. #include "AttrObject.h"
  224. #endif
  225.  
  226. // -- ScriptRunner Includes --
  227.  
  228. #ifndef SOM_PaletteExt_xh
  229. #include "PaletteExt.xh"
  230. #endif
  231.  
  232. #ifndef _SCRIPTRUNNERSUPPORT_
  233. #include "ScriptRunnerSupport.h"
  234. #endif
  235.  
  236.  
  237. //==============================================================================
  238. // Typedefs
  239. //==============================================================================
  240.  
  241. struct DragData
  242. {
  243.     TOffsetRange    dropPoint;
  244.     ODSShort        acceptable;
  245.     ODFacet*        originator;
  246. };
  247.  
  248. //==============================================================================
  249. #pragma mark    • Utility functions •
  250. //==============================================================================
  251.  
  252. //------------------------------------------------------------------------------
  253. // Function:    XorInsertionPoint
  254. //------------------------------------------------------------------------------
  255.  
  256. static void XorInsertionPoint( CTextension* textension, TOffsetRange& range )
  257. {
  258.     if ( range.Start() != -1 )
  259.     {
  260.         short height;
  261.         Point caret = textension->CharToPoint(range.rangeStart, &height);
  262.         
  263.         MoveTo(caret.h, caret.v);
  264.         PenPat(&ODQDGlobals.black);
  265.         PenMode(patXor);
  266.         
  267.         Line(0, height);
  268.         PenNormal();
  269.     }
  270. }
  271.  
  272. //==============================================================================
  273. #pragma mark    • Menus •
  274. //==============================================================================
  275.  
  276. //------------------------------------------------------------------------------
  277. // Method:        AdjustMenus
  278. // Origin:        ODPart
  279. //------------------------------------------------------------------------------
  280.  
  281. SOM_Scope    void
  282. SOMLINK        TextEditor__AdjustMenus
  283.             (
  284.                 SampleCode_TextEditor*        somSelf,
  285.                 Environment*                ev,
  286.                 ODFrame*                    frame
  287.             )
  288. {
  289.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  290.     SOMMethodDebug("TextEditor","AdjustMenus");
  291.  
  292.     SOM_TRY
  293.  
  294.         // The menubar object always calls the root part's AdjustMenus method before
  295.         // calling the menu focus owner's. Because of this, we need to validate the
  296.         // menubar in the case where we are the root part.
  297.         if ( frame->IsRoot(ev) )
  298.         {
  299.             // We are required to re-validate the menubar before displaying it because
  300.             // any part can/could swap the base menubar at any time.
  301.             if ( !gGlobals->fMenuBar->IsValid(ev) )
  302.                 somSelf->LoadMenus(ev);
  303.         }        
  304.     
  305.         TRY
  306.             somSelf->AdjustEditMenu(ev, frame);
  307.                 // Adjust the Edit menu.
  308.             
  309.             somSelf->AdjustTextEditorMenus(ev, frame);
  310.                 // Adjust our menus
  311.         
  312.             somSelf->AdjustDynamicMenuItems(ev, frame);
  313.                 // Change the text of the menu items that are dynamic (e.g. Show/Hide)
  314.     
  315.         CATCH_ALL
  316.             // Consume the exception and prevent it from being propogated.
  317.         ENDTRY
  318.  
  319.     SOM_CATCH_ALL
  320.     SOM_ENDTRY
  321. }
  322.  
  323. //------------------------------------------------------------------------------
  324. // Method:        AdjustEditMenu
  325. // Origin:        TextEditor
  326. //------------------------------------------------------------------------------
  327.  
  328. SOM_Scope    void
  329. SOMLINK        TextEditor__AdjustEditMenu
  330.             (
  331.                 SampleCode_TextEditor*        somSelf,
  332.                 Environment*                ev,
  333.                 ODFrame*                    frame
  334.             )
  335. {
  336.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  337.     SOMMethodDebug("TextEditor","AdjustEditMenu");
  338.  
  339.     SOM_TRY
  340.  
  341.         TOffsetRange    curSelectionRange;
  342.         ODBoolean        realSelection;
  343.  
  344.         // Edit Menu
  345.         
  346.         _fTextension->GetSelectionRange(&curSelectionRange);
  347.         realSelection = ( curSelectionRange.Start() < curSelectionRange.End() );
  348.         
  349.         // If the user has made a selection, enable the Edit commands.
  350.         gGlobals->fMenuBar->EnableCommand(ev, kODCommandCopy,  realSelection);
  351.         gGlobals->fMenuBar->EnableCommand(ev, kODCommandCut,   !_fReadOnlyStorage && realSelection);
  352.         gGlobals->fMenuBar->EnableCommand(ev, kODCommandClear, !_fReadOnlyStorage && realSelection);
  353.             
  354.         // If the is any content, enable this command.
  355.         gGlobals->fMenuBar->EnableCommand(ev, kODCommandSelectAll,
  356.                                     (ODBoolean) _fTextension->CountCharsBytes());
  357.             
  358.         TRY
  359.             ODSession* session = ODGetSession(ev, frame);
  360.         
  361.             ODBoolean mustTranslate = kODFalse;
  362.             ODBoolean validData = kODFalse;
  363.  
  364.             if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fClipboardFocus, frame) )
  365.             {
  366.                 ODStorageUnit* clipboardSU = ODGetSession(ev, somSelf)->GetClipboard(ev)
  367.                                     ->GetContentStorageUnit(ev);
  368.                 
  369.                 // If there is any palatable content on the clipboard, enable the paste
  370.                 // and paste as... commands.
  371.                 mustTranslate = kODFalse;
  372.                 validData = somSelf->HasValidData(ev, clipboardSU, &mustTranslate);
  373.                 
  374.                 session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fClipboardFocus, frame);
  375.             }
  376.             
  377.             gGlobals->fMenuBar->EnableCommand(ev, kODCommandPaste,   
  378.                                               !_fReadOnlyStorage && validData && !mustTranslate);
  379.             gGlobals->fMenuBar->EnableCommand(ev, kODCommandPasteAs, 
  380.                                               !_fReadOnlyStorage && validData && mustTranslate);
  381.         CATCH_ALL
  382.             // It is unfortunate, but not fatal, to not have the Paste menu item
  383.             // enable properly. Therefore, we consume the error.
  384.         ENDTRY
  385.     
  386.         // Enable the "View As Window" command if the frame is not the root
  387.         // frame of the window.
  388.     //    gGlobals->fMenuBar->EnableCommand(ev, kODCommandViewAsWin, !frame->IsRoot(ev));
  389.         // Currently, we don't support View In Window, so dim that item.
  390.         gGlobals->fMenuBar->EnableCommand(ev, kODCommandViewAsWin, kODFalse);
  391.         
  392.         // Always enable "Preferences".
  393.         gGlobals->fMenuBar->EnableCommand(ev, kODCommandPreferences, kODTrue);
  394.  
  395.     SOM_CATCH_ALL
  396.     SOM_ENDTRY
  397. }
  398.  
  399. //------------------------------------------------------------------------------
  400. // Method:        AdjustTextEditorMenus
  401. // Origin:        TextEditor
  402. //------------------------------------------------------------------------------
  403.  
  404. SOM_Scope    void
  405. SOMLINK        TextEditor__AdjustTextEditorMenus
  406.             (
  407.                 SampleCode_TextEditor*        somSelf,
  408.                 Environment*                ev,
  409.                 ODFrame*                    frame
  410.             )
  411. {
  412.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  413.     SOMMethodDebug("TextEditor","AdjustTextEditorMenus");
  414.  
  415.     SOM_TRY
  416.     
  417.         ODMenuBar* mbar = gGlobals->fMenuBar;
  418.     
  419.         // Font, Size, Style Menus
  420.         
  421.         const CRunObject* continuousRun = _fTextension->GetContinuousRun();
  422.         ODSLong value;
  423.         
  424.         // Font.
  425.         MenuHandle fontMenu = mbar->GetMenu(ev, kFontMenuID);
  426.         
  427.         for (int i=1; i <= CountMItems(fontMenu); i++)
  428.         {
  429.             mbar->CheckCommand(ev, mbar->GetCommand(ev, kFontMenuID, i), kODFalse);
  430.         }
  431.             
  432.         if ( continuousRun->GetAttributeValue(kFontAttr, &value) )
  433.         {
  434.             value = value >> 16;
  435.             
  436.             if ( value == applFont )
  437.             {
  438.                 long result = GetScriptVariable(smSystemScript, smScriptAppFondSize);
  439.                 value = HiWord(result);        // hi-word contains font number.
  440.             }
  441.             
  442.             ODCommandID command = kBaseFontCmdID + value;
  443.             
  444.             mbar->CheckCommand(ev, kBaseFontCmdID+value, kODTrue);
  445.         
  446.             somSelf->RealFontSizeMenu(ev, value);
  447.         }
  448.         
  449.         // Size.
  450.         if ( continuousRun->GetAttributeValue(kFontSizeAttr, &value) )
  451.             value = value >> 16;
  452.         else
  453.             value = -1;
  454.             
  455.         mbar->CheckCommand(ev, kBaseFontSizeCmdID +  9, (value ==  9));
  456.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 10, (value == 10));
  457.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 12, (value == 12));
  458.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 14, (value == 14));
  459.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 18, (value == 18));
  460.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 24, (value == 24));
  461.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 36, (value == 36));
  462.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 48, (value == 48));
  463.         mbar->CheckCommand(ev, kBaseFontSizeCmdID + 72, (value == 72));
  464.         
  465.         // Set up the checkmark on the "Other" size menu item.
  466.         switch ((ODSShort) value)
  467.         {
  468.             case -1:
  469.             case  9:
  470.             case 10:
  471.             case 12:
  472.             case 14:
  473.             case 18:
  474.             case 24:
  475.             case 36:
  476.             case 48:
  477.             case 72:
  478.                 mbar->CheckCommand(ev, kOtherFontSizeCmdID, kODFalse);
  479.                 break;
  480.                 
  481.             default:
  482.                 mbar->CheckCommand(ev, kOtherFontSizeCmdID, kODTrue);
  483.         }
  484.         
  485.         // Style.
  486.         if ( continuousRun->GetAttributeValue(kFaceAttr, &value) )
  487.         {
  488.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + normal,     (value == normal));
  489.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + bold,         (value & bold)      != 0);
  490.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + italic,     (value & italic)    != 0);
  491.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + underline,    (value & underline) != 0);
  492.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + outline,      (value & outline)   != 0);
  493.         }
  494.         else
  495.         {
  496.             // There is more than one run of differently-styled text in the current
  497.             // selection.  For now, just uncheck everything.
  498.               
  499.             // The proper user interface for this would be do walk the runs and mark 
  500.             // each style that was found in all runs with a check mark and any other 
  501.             // style that was found in only SOME of the runs with a dash character.
  502.     
  503.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + normal,     kODFalse);
  504.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + bold,         kODFalse);
  505.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + italic,     kODFalse);
  506.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + underline,    kODFalse);
  507.             mbar->CheckCommand(ev, kBaseFontStyleCmdID + outline,     kODFalse);
  508.         }
  509.     
  510.     SOM_CATCH_ALL
  511.     SOM_ENDTRY
  512. }
  513.  
  514. //------------------------------------------------------------------------------
  515. // Method:        AdjustDynamicMenuItems
  516. // Origin:        TextEditor
  517. //------------------------------------------------------------------------------
  518.  
  519. SOM_Scope    void
  520. SOMLINK        TextEditor__AdjustDynamicMenuItems
  521.             (
  522.                 SampleCode_TextEditor*        somSelf,
  523.                 Environment*                ev,
  524.                 ODFrame*                    frame
  525.             )
  526. {
  527.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  528.     SOMMethodDebug("TextEditor","AdjustDynamicMenuItems");
  529.  
  530.     SOM_TRY
  531.     
  532.         TRY
  533.             ODArbitrator* arbitrator = ODGetSession(ev, somSelf)->GetArbitrator(ev);
  534.             TempODFrame menuOwner = arbitrator->AcquireFocusOwner(ev, gGlobals->fMenuFocus);
  535.         
  536.             // There is no need to load a resource, create an ODIText object, set the menubar,
  537.             // and cleanup, if we don't own the menu focus.
  538.             if ( ODObjectsAreEqual(ev, frame, menuOwner) )
  539.             {
  540.                 // Change the "About…" item text for our part.
  541.                 SetMenuCommandIndString(ev, kODCommandAbout, kRuntimeStringsID, kAboutTextStrIndex);
  542.                 
  543.                 // Change the "Preferences" item text for our part.
  544.                 SetMenuCommandIndString(ev, kODCommandPreferences, kRuntimeStringsID, kPreferencesStrIndex);
  545.                 
  546.                 gGlobals->fMenuBar->EnableCommand(ev, kShowHideRulerCmdID, kODFalse);
  547.     /*
  548.                 if ( _fRulerPalette != kODNULLID )
  549.                     SetMenuCommandIndString(ev, kShowHideRulerCmdID, kRuntimeStringsID, kHideRulerStrIndex);
  550.                 else
  551.                     SetMenuCommandIndString(ev, kShowHideRulerCmdID, kRuntimeStringsID, kShowRulerStrIndex);
  552.     */            
  553.  
  554.                 // Set up the items in the tools menu.
  555.                 
  556.                 somSelf->UpdateScriptRunnerState(ev);
  557.                 SetMenuCommandIndString(ev, kToggleScriptRunnerCmdID, kRuntimeStringsID, 
  558.                                         _fIsScriptRunnerOn ? kHideScriptRunnerStrIndex
  559.                                                            : kShowScriptRunnerStrIndex);
  560.                 
  561.                 Boolean installed = (_fScriptPaletteExt != kODNULL)
  562.                                     || IsScriptRunnerInstalled(ev, ODGetSession(ev, _fSelf));
  563.                 
  564.                 gGlobals->fMenuBar->EnableCommand(ev, kToggleScriptRunnerCmdID, 
  565.                                                   !_fReadOnlyStorage && installed);
  566.  
  567.                 // Set up Settings menu item.
  568.                 
  569.                 gGlobals->fMenuBar->EnableCommand(ev, kSettingsCmdID, 
  570.                                                   !_fReadOnlyStorage);
  571.             }
  572.         CATCH_ALL
  573.         ENDTRY
  574.  
  575.     SOM_CATCH_ALL
  576.     SOM_ENDTRY
  577. }
  578.  
  579. //==============================================================================
  580. #pragma mark    • Event Handling •
  581. //==============================================================================
  582.  
  583. //------------------------------------------------------------------------------
  584. // Method:        HandleEvent
  585. // Origin:        ODPart
  586. //------------------------------------------------------------------------------
  587. #pragma segment TextEditorEvents
  588.  
  589. SOM_Scope    ODBoolean
  590. SOMLINK        TextEditor__HandleEvent
  591.             (
  592.                 SampleCode_TextEditor*        somSelf,
  593.                 Environment*                ev,
  594.                 ODEventData*                event,
  595.                 ODFrame*                    frame,
  596.                 ODFacet*                    facet,
  597.                 ODEventInfo*                eventInfo
  598.             )
  599. {
  600.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  601.     SOMMethodDebug("TextEditor","HandleEvent");
  602.  
  603.     ODBoolean eventHandled = kODFalse;
  604.     
  605.     SOM_TRY
  606.     
  607.         // Event handling is basically the same as standard Macintosh applications,
  608.         // except that the events have been renamed for cross-platform compatability.
  609.         
  610.         switch ( event->what )
  611.         {
  612.             case kODEvtMouseDown:
  613.             case kODEvtMouseUp:
  614.             case kODEvtBGMouseDown:
  615.                 eventHandled = somSelf->HandleMouseEvent(ev, event, facet, eventInfo);
  616.                 break;
  617.                             
  618.             case kODEvtMenu:
  619.                 eventHandled = somSelf->HandleMenuEvent(ev, event, frame);
  620.                 break;
  621.     
  622.             case kODEvtActivate:
  623.                 // We are being notified that a window we are displayed in has
  624.                 // just been activated/deactivated (hilighted/unhilighted).
  625.                 somSelf->WindowActivating(ev, frame, (event->modifiers & activeFlag));
  626.                 eventHandled = kODTrue;
  627.                 break;
  628.         
  629.             case kODEvtAutoKey:
  630.             case kODEvtKeyDown:
  631.                 eventHandled = somSelf->HandleKeyboardEvent(ev, event, frame);
  632.                 break;
  633.             
  634.             case kODEvtMouseEnter:
  635.                 somSelf->MouseEnter(ev, facet, &(eventInfo->where));
  636.                 eventHandled = kODTrue;
  637.                 break;
  638.                 
  639.             case kODEvtMouseWithin:
  640.                 somSelf->MouseWithin(ev, facet, &(eventInfo->where));
  641.                 eventHandled = kODTrue;
  642.                 break;
  643.     
  644.             case kODEvtMouseLeave:
  645.                 somSelf->MouseLeave(ev, facet);
  646.                 eventHandled = kODTrue;
  647.                 break;
  648.     
  649.             case kODEvtOS:
  650.                 somSelf->WindowActivating(ev, frame, (event->message & resumeFlag));
  651.                     // We are being notified that a window we are display in has
  652.                     // just been suspened/resumed.
  653.                 eventHandled = kODTrue;
  654.                 break;
  655.             
  656.             case kODEvtWindow:
  657.                 eventHandled = somSelf->HandleWindowEvent(ev, event, frame);
  658.                 break;
  659.             
  660.             // Other events a part might handle:
  661.             case kODEvtNull:
  662.                 somSelf->DoIdle(ev, frame);
  663.                 break;
  664.     
  665.             case kODEvtMouseDownBorder:
  666.             case kODEvtKeyUp:
  667.             case kODEvtDisk:
  668.             default:
  669.                 break;
  670.         }
  671.  
  672.     SOM_CATCH_ALL
  673.     SOM_ENDTRY
  674.  
  675.     return eventHandled;
  676. }
  677.  
  678. //------------------------------------------------------------------------------
  679. // Method:        HandleMenuEvent
  680. // Origin:        TextEditor
  681. //------------------------------------------------------------------------------
  682.  
  683. SOM_Scope    ODBoolean
  684. SOMLINK        TextEditor__HandleMenuEvent
  685.             (
  686.                 SampleCode_TextEditor*        somSelf,
  687.                 Environment*                ev,
  688.                 ODEventData*                event,
  689.                 ODFrame*                    frame
  690.             )
  691. {
  692.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  693.     SOMMethodDebug("TextEditor","HandleMenuEvent");
  694.  
  695.     SOM_TRY
  696.  
  697.         ODUShort    menu    = HiWord(event->message);
  698.         ODUShort    item    = LoWord(event->message);
  699.         ODID        command    = gGlobals->fMenuBar->GetCommand(ev, menu, item);
  700.     
  701.         switch( command ) {
  702.     
  703.             case kODCommandAbout:
  704.                 somSelf->DoAboutBox(ev, frame);
  705.                 break;
  706.     
  707.             case kODCommandViewAsWin:
  708.                 somSelf->Open(ev, frame);
  709.                 break;
  710.     
  711.             case kODCommandCut:
  712.                 somSelf->DoCut(ev, frame);
  713.                 break;
  714.                 
  715.             case kODCommandCopy:
  716.                 somSelf->DoCopy(ev, frame);
  717.                 break;
  718.                 
  719.             case kODCommandPaste:
  720.                 somSelf->DoPaste(ev, frame);
  721.                 break;
  722.                 
  723.             case kODCommandPasteAs:
  724.                 somSelf->DoPasteAs(ev, frame);
  725.                 break;
  726.                 
  727.             case kODCommandClear:
  728.                 somSelf->DoClear(ev, frame);
  729.                 break;
  730.                 
  731.             case kODCommandSelectAll:
  732.                 somSelf->DoSelectAll(ev, frame);
  733.                 break;
  734.                 
  735.             case kODCommandPageSetup:
  736.                 somSelf->DoPageSetup(ev, frame);
  737.                 break;
  738.                 
  739.             case kODCommandPrint:
  740.                 somSelf->DoPrint(ev, frame);
  741.                 break;
  742.                 
  743.             case kODCommandPreferences:
  744.                 somSelf->DoPreferences(ev, frame);
  745.                 break;
  746.                 
  747.             case kShowHideRulerCmdID:
  748.                 somSelf->ShowHideRuler(ev, frame);
  749.                 break;
  750.             
  751.             case kSettingsCmdID:
  752.                 somSelf->DoSettings(ev, frame);
  753.                 break;
  754.                 
  755.             case kToggleScriptRunnerCmdID:
  756.                 if ( _fScriptPaletteExt == kODNULL 
  757.                      && IsScriptRunnerInstalled(ev, ODGetSession(ev, _fSelf)) )
  758.                 {
  759.                     _fScriptPaletteExt = AcquireScriptRunner(ev, ODGetDraft(ev, somSelf));
  760.                     _fScriptPaletteExt->SetClient(ev, _fSelf);
  761.                 }
  762.                 
  763.                 if ( _fScriptPaletteExt )
  764.                 {
  765.                     if ( _fIsScriptRunnerOn )
  766.                     {
  767.                         _fScriptPaletteExt->Hide(ev);
  768.                         ODReleaseObject(ev, _fScriptPaletteExt);
  769.                         _fIsScriptRunnerHidden = kODFalse;
  770.                     }
  771.                     else
  772.                     {
  773.                         _fScriptPaletteExt->Show(ev);
  774.                         _fIsScriptRunnerHidden = kODFalse;
  775.                     }
  776.                 }
  777.                 
  778.                 _fIsScriptRunnerOn = !_fIsScriptRunnerOn;
  779.                 
  780.                 if ( !_fReadOnlyStorage )
  781.                     somSelf->SetDirty(ev);
  782.                 break;
  783.                 
  784.             default:
  785.                 return somSelf->DoTextStyling(ev, frame, command);
  786.         }
  787.         
  788.     SOM_CATCH_ALL
  789.     SOM_ENDTRY
  790.  
  791.     return kODTrue;
  792. }
  793.  
  794. //------------------------------------------------------------------------------
  795. // Method:        HandleWindowEvent
  796. // Origin:        TextEditor
  797. //
  798. // Description:    This method is called by the part to handle user event in a
  799. //                window.
  800. //
  801. //                The part never actually destoys windows when they are closed by
  802. //                the user; they are merely hidden until the document is closed.
  803. //------------------------------------------------------------------------------
  804.  
  805. SOM_Scope    ODBoolean
  806. SOMLINK        TextEditor__HandleWindowEvent
  807.             (
  808.                 SampleCode_TextEditor*        somSelf,
  809.                 Environment*                ev,
  810.                 ODEventData*                event,
  811.                 ODFrame*                    frame
  812.             )
  813. {
  814.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  815.     SOMMethodDebug("TextEditor","HandleWindowEvent");
  816.     
  817.     ODBoolean handled = kODFalse;
  818.     
  819.     SOM_TRY
  820.  
  821.         // This function is unneeded.  It was left in for possible future 
  822.         // use for a ruler window.
  823.     
  824.     SOM_CATCH_ALL
  825.     SOM_ENDTRY
  826.  
  827.     return handled;
  828. }
  829.  
  830.  
  831. //------------------------------------------------------------------------------
  832. // Method:        HandleMouseEvent
  833. // Origin:        TextEditor
  834. //------------------------------------------------------------------------------
  835.  
  836. SOM_Scope    ODBoolean
  837. SOMLINK        TextEditor__HandleMouseEvent
  838.             (
  839.                 SampleCode_TextEditor*        somSelf,
  840.                 Environment*                ev,
  841.                 ODEventData*                event,
  842.                 ODFacet*                    facet,
  843.                 ODEventInfo*                eventInfo
  844.             )
  845. {
  846.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  847.     SOMMethodDebug("TextEditor","HandleMouseEvent");
  848.  
  849.     SOM_TRY
  850.     
  851.         ODFrame* frame = facet->GetFrame(ev);
  852.         
  853.         // If the facet parameter is invalid, the mouse up occurred outside the
  854.         // bounds of a Modal window, otherwise it should be treated normally.
  855.         
  856.         if (facet != kODNULL)
  857.         {
  858.             if ( frame->GetPresentation(ev) == gGlobals->fMainPresentation )
  859.             {    
  860.                 // Activate the window and frame unless it's a mouse down in an
  861.                 // inactive window because it may become a background drag operation.
  862.                 
  863.                 if ( event->what != kODEvtBGMouseDown )
  864.                     if ( somSelf->Activate(ev, facet) == kODFalse )
  865.                         return kODFalse;
  866.         
  867.                 if ( event->what == kODEvtMouseDown ||
  868.                         event->what == kODEvtBGMouseDown )                
  869.                 {
  870.                     Point where;
  871.             
  872.                     // Get the localized mouse coordinates from the Event Info.
  873.                     where.h = FixedToInt(eventInfo->where.x);
  874.                     where.v = FixedToInt(eventInfo->where.y);
  875.                 
  876.                     // Handle the mouse down event.
  877.                     somSelf->DoMouseEvent(ev, facet, &where, event);
  878.                 }
  879.             }
  880.             // For now, the ruler is "dumb". We could allow the user to set tabs
  881.             // on the ruler.
  882.             else if ( frame->GetPresentation(ev) == gGlobals->fRulerPresentation )
  883.             {
  884.                 somSelf->HandleRulerMouseEvent(ev, event, facet, eventInfo);
  885.             }
  886.         }
  887.         else
  888.         {
  889.             // User clicked outside the bounds of a Modal window.            
  890.             SysBeep(1);
  891.         }
  892.  
  893.     SOM_CATCH_ALL
  894.     SOM_ENDTRY
  895.  
  896.     return kODTrue;
  897. }
  898.  
  899. //------------------------------------------------------------------------------
  900. // Method:        HandleMouseEvent
  901. // Origin:        TextEditor
  902. //------------------------------------------------------------------------------
  903.  
  904. SOM_Scope    ODBoolean
  905. SOMLINK        TextEditor__HandleRulerMouseEvent
  906.             (
  907.                 SampleCode_TextEditor*        somSelf,
  908.                 Environment*                ev,
  909.                 ODEventData*                event,
  910.                 ODFacet*                    facet,
  911.                 ODEventInfo*                eventInfo
  912.             )
  913. {
  914.    // SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  915.     SOMMethodDebug("TextEditor","HandleRulerMouseEvent");
  916.  
  917.     return kODTrue;
  918. }
  919.  
  920. //------------------------------------------------------------------------------
  921. // Method:        HandleKeyboardEvent
  922. // Origin:        TextEditor
  923. //------------------------------------------------------------------------------
  924.  
  925. SOM_Scope    ODBoolean
  926. SOMLINK        TextEditor__HandleKeyboardEvent
  927.             (
  928.                 SampleCode_TextEditor*        somSelf,
  929.                 Environment*                ev,
  930.                 ODEventData*                event,
  931.                 ODFrame*                    frame
  932.             )
  933. {
  934.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  935.     SOMMethodDebug("TextEditor","HandleKeyboardEvent");
  936.  
  937.     ODBoolean result = kODFalse;
  938.  
  939.     SOM_TRY
  940.     
  941.         if ( event->modifiers & cmdKey ) 
  942.         {
  943.             result = kODFalse;
  944.         }
  945.         else
  946.         {
  947.             if ( _fReadOnlyStorage && KeyCausesModification(event) )
  948.                 return kODFalse;
  949.             
  950.             TKeyDownFlags    flags;
  951.             CFrameInfo*        frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
  952.             ODFacet*        activeFacet = frameInfo->GetActiveFacet();
  953.             
  954.             // •• Need to handle page-up, page-down, home, end, etc.
  955.             
  956.             {    
  957.                 CFocus initiateDrawing(ev, activeFacet);
  958.                 flags = _fTextension->KeyDown(*(EventRecord*) event);
  959.             }
  960.             
  961.             if ( flags & kKeyDownHandled )
  962.             {
  963.                 // Certain keys, like arrows, shouldn't make the part dirty.
  964.                 if ( !(flags & kArrowKey) )
  965.                     somSelf->HandleChange(ev);
  966.             
  967.                 somSelf->MakeSelectionVisible(ev, frame);
  968.  
  969.                 // <new method>
  970.                 // get frames
  971.                 // if ( frames->IsLastFrameOverflow() )
  972.                 // {
  973.                 //      request grow vertically
  974.                 //      if not ok
  975.                 //            request grow horizontally
  976.                 //            if not ok
  977.                 //                add new frame with same width, just below
  978.                 //
  979.             }
  980.         
  981.             result = ( flags & kKeyDownHandled );
  982.         }
  983.         
  984.     SOM_CATCH_ALL
  985.     SOM_ENDTRY
  986.  
  987.     return result;
  988. }
  989.  
  990. //==============================================================================
  991. #pragma mark    • Mouse Tracking •
  992. //==============================================================================
  993.  
  994. //------------------------------------------------------------------------------
  995. // Method:        MouseEnter
  996. // Origin:        TextEditor
  997. //------------------------------------------------------------------------------
  998.  
  999. SOM_Scope    void
  1000. SOMLINK        TextEditor__MouseEnter
  1001.             (
  1002.                 SampleCode_TextEditor*        somSelf,
  1003.                 Environment*                ev,
  1004.                 ODFacet*                    facet,
  1005.                 ODPoint*                    where
  1006.             )
  1007. {
  1008.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1009.     SOMMethodDebug("TextEditor","MouseEnter");
  1010.  
  1011.     SOM_TRY
  1012.  
  1013.         somSelf->MouseWithin(ev, facet, where);
  1014.  
  1015.     SOM_CATCH_ALL
  1016.     SOM_ENDTRY
  1017. }
  1018.  
  1019.  
  1020. //------------------------------------------------------------------------------
  1021. // Method:        MouseWithin
  1022. // Origin:        TextEditor
  1023. //------------------------------------------------------------------------------
  1024.  
  1025. SOM_Scope    void
  1026. SOMLINK        TextEditor__MouseWithin
  1027.             (
  1028.                 SampleCode_TextEditor*        somSelf,
  1029.                 Environment*                ev,
  1030.                 ODFacet*                    facet,
  1031.                 ODPoint*                    where
  1032.             )
  1033. {
  1034.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1035.     SOMMethodDebug("TextEditor","MouseWithin");
  1036.  
  1037.     SOM_TRY
  1038.  
  1039.         Point        mouse;
  1040.         ODFrame*    frame = facet->GetFrame(ev);
  1041.     
  1042.         mouse.h = FixedToInt(where->x);
  1043.         mouse.v = FixedToInt(where->y);
  1044.         
  1045.         if ( frame->GetPresentation(ev) == gGlobals->fMainPresentation )
  1046.         {    
  1047.             // optimization opportunity: should try to calculate this less often.
  1048.             somSelf->CalcSelectionRgn(ev, facet);    
  1049.             
  1050.             if ( PtInRgn(mouse, (RgnHandle) _fSelectionRgn) )
  1051.             {
  1052.                 SetCursor(&ODQDGlobals.arrow);
  1053.             }
  1054.             else if ( frame->IsRoot(ev) && 
  1055.                       ( PtInRect(mouse, &((**_fVScrollbar).contrlRect)) || 
  1056.                         PtInRect(mouse, &((**_fHScrollbar).contrlRect)) ) ) 
  1057.             {
  1058.                 SetCursor(&ODQDGlobals.arrow);
  1059.             }
  1060.             else
  1061.             {
  1062.                 SetCursor(*GetCursor(iBeamCursor)); 
  1063.             }
  1064.         }
  1065.         else
  1066.         {
  1067.             SetCursor(&ODQDGlobals.arrow);
  1068.         }
  1069.  
  1070.     SOM_CATCH_ALL
  1071.     SOM_ENDTRY
  1072. }
  1073.  
  1074. //------------------------------------------------------------------------------
  1075. // Method:        MouseLeave
  1076. // Origin:        TextEditor
  1077. //------------------------------------------------------------------------------
  1078.  
  1079. SOM_Scope    void
  1080. SOMLINK        TextEditor__MouseLeave
  1081.             (
  1082.                 SampleCode_TextEditor*        somSelf,
  1083.                 Environment*                ev,
  1084.                 ODFacet*                    facet
  1085.             )
  1086. {
  1087.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1088.     SOMMethodDebug("TextEditor","MouseLeave");
  1089.  
  1090.     SetCursor(&ODQDGlobals.arrow);
  1091. }
  1092.  
  1093. //==============================================================================
  1094. #pragma mark    • Drag and Drop •
  1095. //==============================================================================
  1096.  
  1097. //------------------------------------------------------------------------------
  1098. // Method:        DragEnter
  1099. // Origin:        ODPart
  1100. //------------------------------------------------------------------------------
  1101.  
  1102. SOM_Scope    ODDragResult
  1103. SOMLINK        TextEditor__DragEnter
  1104.             (
  1105.                 SampleCode_TextEditor*        somSelf,
  1106.                 Environment*                ev,
  1107.                 ODDragItemIterator*            dragInfo,
  1108.                 ODFacet*                    facet,
  1109.                 ODPoint*                    where
  1110.             )
  1111. {
  1112.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1113.     SOMMethodDebug("TextEditor","DragEnter");
  1114.  
  1115.     ODDragResult dragOK = kODFalse;
  1116.  
  1117.     SOM_TRY
  1118.         
  1119.         // Don't allow dropping in a read only part.
  1120.         if ( _fReadOnlyStorage )
  1121.             return kODFalse;
  1122.         
  1123.         // Don't allow dropping in icon or thumbnail views.
  1124.         if ( facet->GetFrame(ev)->GetViewType(ev) != gGlobals->fFrameView )
  1125.             return kODFalse;
  1126.         
  1127.         // If we haven't set up a drag tracking structure yet, do so now.
  1128.         if ( _fDragData == kODNULL)
  1129.         {
  1130.             TOffsetRange curSelectionRange((long) -1, (long) 0);
  1131.         
  1132.             //_fTextension->GetSelectionRange(&curSelectionRange);
  1133.     
  1134.             _fDragData = new DragData;
  1135.     
  1136.             _fDragData->dropPoint = curSelectionRange;
  1137.             _fDragData->acceptable = kUndefined;
  1138.             _fDragData->originator = kODNULL;
  1139.         }
  1140.         
  1141.         // If we are dragging our own data in one of our own facets, we know 
  1142.         // the data is valid; otherwise, we must check.
  1143.         if ( _fDragData->originator )
  1144.         {
  1145.             ODFacet* sourceFacet = _fDragData->originator;
  1146.             TempODPart sourcePart = sourceFacet->GetFrame(ev)->AcquirePart(ev);
  1147.             TempODPart destPart = facet->GetFrame(ev)->AcquirePart(ev);
  1148.             
  1149.             if ( ODObjectsAreEqual(ev, sourcePart, destPart) )
  1150.                 dragOK = kODTrue;
  1151.         }
  1152.         
  1153.         // If the above test didn't give us the info we needed, validate the contents
  1154.         // of the drag.
  1155.         if ( !dragOK )
  1156.         {
  1157.             for ( ODStorageUnit* dragSU = dragInfo->First(ev); dragSU; 
  1158.                   dragSU = dragInfo->Next(ev) )
  1159.             {
  1160.                 ODBoolean mustTranslate = kODFalse;
  1161.                 if (somSelf->HasValidData(ev, dragSU, &mustTranslate))
  1162.                     dragOK = kODTrue;
  1163.             }
  1164.         }
  1165.         
  1166.         // Use the arrow cursor for drop tracking
  1167.         SetCursor(&ODQDGlobals.arrow);
  1168.             
  1169.         // Set the drag validity and corresponding cursor.
  1170.         if ( dragOK )
  1171.         {
  1172.             // The data in the D&D storage unit is valid data
  1173.             _fDragData->acceptable = kODTrue;
  1174.             
  1175.             // Get the toolbox reference for the current drag operation.
  1176.             ODDragAndDrop* dad = ODGetSession(ev, somSelf)->GetDragAndDrop(ev);
  1177.                                         
  1178.             // Show the Mac Drag Mgr highlighting in our frame.
  1179.             if ( !(dad->GetDragAttributes(ev) & kODDragIsInSourceFrame) )
  1180.             {
  1181.                 CFocus initiateDrawing(ev, facet);        
  1182.  
  1183.                 // Calculate a region to be used for dragging feedback.
  1184.                 CFrames* frames = _fTextension->GetFramesHandler();
  1185.                 Rect textRect;
  1186.                 frames->GetTextBounds(0, &textRect);
  1187.                 if ( facet->GetFrame(ev)->IsRoot(ev) )
  1188.                     InsetRect(&textRect, -6, -6);
  1189.             
  1190.                 RgnHandle dragHilite = ODNewRgn();
  1191.                 RectRgn(dragHilite, &textRect);
  1192.                                         
  1193.                 ShowDragHilite(dad->GetDragReference(ev), dragHilite, true);
  1194.             
  1195.                 ODDisposeHandle((ODHandle) dragHilite);
  1196.             }
  1197.         }
  1198.         
  1199.     SOM_CATCH_ALL
  1200.     
  1201.         dragOK = kODFalse;
  1202.         
  1203.     SOM_ENDTRY
  1204.     
  1205.     return dragOK;
  1206. }
  1207.  
  1208. //------------------------------------------------------------------------------
  1209. // Method:        DragWithin
  1210. // Origin:        ODPart
  1211. //------------------------------------------------------------------------------
  1212.  
  1213. SOM_Scope    ODDragResult
  1214. SOMLINK        TextEditor__DragWithin
  1215.             (
  1216.                 SampleCode_TextEditor*        somSelf,
  1217.                 Environment*                ev,
  1218.                 ODDragItemIterator*            dragInfo,
  1219.                 ODFacet*                    facet,
  1220.                 ODPoint*                    where
  1221.             )
  1222. {
  1223.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1224.     SOMMethodDebug("TextEditor","DragWithin");
  1225.  
  1226.     ODBoolean result = kODTrue;
  1227.  
  1228.     SOM_TRY
  1229.     
  1230.         // Don't allow dropping in a read only part.
  1231.         if ( _fReadOnlyStorage )
  1232.             return kODFalse;
  1233.     
  1234.         // Don't allow dropping in icon or thumbnail views.
  1235.         if ( facet->GetFrame(ev)->GetViewType(ev) != gGlobals->fFrameView )
  1236.             return kODFalse;
  1237.         
  1238.         // If the acceptabability is not yet defined, call DragEnter to assess it.
  1239.     
  1240.         if ( _fDragData->acceptable == kUndefined )
  1241.             somSelf->DragEnter(ev, dragInfo, facet, where);
  1242.             
  1243.         // If the drag data is unacceptable, just exit.
  1244.         if ( !_fDragData->acceptable )
  1245.         {
  1246.             result = kODFalse;
  1247.         }
  1248.         else
  1249.         {
  1250.             // Otherwise, track the mouse with the insertion point.
  1251.         
  1252.             CFocus initiateDrawing(ev, facet);
  1253.                     
  1254.             Point pt;
  1255.             pt.v = FixedToInt(where->y); 
  1256.             pt.h = FixedToInt(where->x);
  1257.             
  1258.             TOffsetRange curDropRange;
  1259.             ODBoolean outsideFrame;
  1260.             ODBoolean outsideLine;
  1261.  
  1262.             const CRunObject* run = _fTextension->PointToChar(pt, &curDropRange, 
  1263.                                                               &outsideFrame, &outsideLine);
  1264.  
  1265.             if ( curDropRange.Start() != _fDragData->dropPoint.Start() )
  1266.             {
  1267.                 // Erase old insertion point.
  1268.                 XorInsertionPoint(_fTextension, _fDragData->dropPoint);
  1269.                 
  1270.                 // Check the new drop location.
  1271.                 
  1272.                 TOffsetRange curSelectionRange;
  1273.                 _fTextension->GetSelectionRange(&curSelectionRange);
  1274.                 
  1275.                 // Determine if the drop is in the originating part.
  1276.                 ODBoolean isInOriginatingPart = kODFalse;
  1277.                 if ( _fDragData->originator )
  1278.                 {
  1279.                     TempODPart sourcePart = _fDragData->originator->GetFrame(ev)->AcquirePart(ev);
  1280.                     
  1281.                     if ( ODObjectsAreEqual(ev, sourcePart, _fSelf) )
  1282.                         isInOriginatingPart = kODTrue;
  1283.                 }
  1284.                 
  1285.                 if ( isInOriginatingPart &&
  1286.                      curDropRange.Start() >= curSelectionRange.Start() &&
  1287.                      curDropRange.Start() <= curSelectionRange.End() )
  1288.                 {
  1289.                     // We're in the selection range, so don't draw a caret.
  1290.                     
  1291.                     // Set rangeStart to -1 to flag that it is not being drawn.
  1292.                     _fDragData->dropPoint.rangeStart = -1;
  1293.                 }
  1294.                 else
  1295.                 {
  1296.                     // Draw new insertion point.
  1297.                     _fDragData->dropPoint = curDropRange;
  1298.                     XorInsertionPoint(_fTextension, _fDragData->dropPoint);
  1299.                 }
  1300.             }
  1301.         }
  1302.     
  1303.     SOM_CATCH_ALL
  1304.     
  1305.         result = kODFalse;
  1306.         
  1307.     SOM_ENDTRY
  1308.         
  1309.     return result;
  1310. }
  1311.  
  1312. //------------------------------------------------------------------------------
  1313. // Method:        DragLeave
  1314. // Origin:        ODPart
  1315. //------------------------------------------------------------------------------
  1316.  
  1317. SOM_Scope    void
  1318. SOMLINK        TextEditor__DragLeave
  1319.             (
  1320.                 SampleCode_TextEditor*        somSelf, 
  1321.                 Environment*                ev,
  1322.                 ODFacet*                    facet,
  1323.                 ODPoint*                    where
  1324.             )
  1325. {
  1326.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1327.     SOMMethodDebug("TextEditor","DragLeave");
  1328.     
  1329.     SOM_TRY
  1330.     
  1331.         // Don't allow dropping in a read only part.
  1332.         if ( _fReadOnlyStorage )
  1333.             return;
  1334.     
  1335.         // Don't allow dropping in icon or thumbnail views.
  1336.         if ( facet->GetFrame(ev)->GetViewType(ev) != gGlobals->fFrameView )
  1337.             return;
  1338.         
  1339.         DragReference dragRef = ODGetSession(ev, somSelf)->GetDragAndDrop(ev)
  1340.                                     ->GetDragReference(ev);
  1341.     
  1342.         CFocus initiateDrawing(ev, facet);        
  1343.     
  1344.         // Hide the Mac Drag Mgr highlighting.
  1345.         HideDragHilite(dragRef);
  1346.         
  1347.         // Erase the last insertion pt.
  1348.         XorInsertionPoint(_fTextension, _fDragData->dropPoint);
  1349.         
  1350.         // Set rangeStart to -1 to flag that it is not being drawn.
  1351.         _fDragData->dropPoint.rangeStart = -1;
  1352.         
  1353.         // If the drag didn't originate with us, we clean up the temporary
  1354.         // drag structure here.
  1355.         
  1356.         if ( _fDragData->originator == kODNULL )
  1357.         {
  1358.             ODDeleteObject(_fDragData);
  1359.             _fDragData = kODNULL;
  1360.         }
  1361.     
  1362.     SOM_CATCH_ALL
  1363.     SOM_ENDTRY
  1364. }
  1365.  
  1366. //------------------------------------------------------------------------------
  1367. // Method:        Drop
  1368. // Origin:        ODPart
  1369. //------------------------------------------------------------------------------
  1370.  
  1371. SOM_Scope    ODDropResult
  1372. SOMLINK        TextEditor__Drop
  1373.             (    
  1374.                 SampleCode_TextEditor*        somSelf,
  1375.                 Environment*                ev,
  1376.                 ODDragItemIterator*            dropInfo,
  1377.                 ODFacet*                    facet,
  1378.                 ODPoint*                    where
  1379.             )
  1380. {
  1381.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1382.     SOMMethodDebug("TextEditor","Drop");
  1383.     
  1384.     ODDropResult result = kODDropFail;
  1385.  
  1386.     SOM_TRY
  1387.         
  1388.         if ( _fReadOnlyStorage || !_fDragData->acceptable )
  1389.             return kODDropFail;
  1390.         
  1391.         // Don't allow dropping in icon or thumbnail views.
  1392.         if ( facet->GetFrame(ev)->GetViewType(ev) != gGlobals->fFrameView )
  1393.             return kODDropFail;
  1394.         
  1395.         // Prepare the drawing environment.
  1396.         CFocus initiateDrawing(ev, facet);
  1397.             
  1398.         ODFrame*    frame = facet->GetFrame(ev);
  1399.         ODSession*    session = ODGetSession(ev, somSelf);
  1400.         
  1401.         ODULong dragAttributes = session->GetDragAndDrop(ev)->GetDragAttributes(ev);
  1402.  
  1403.         // Erase last insertion point.
  1404.         XorInsertionPoint(_fTextension, _fDragData->dropPoint);
  1405.                 
  1406.         DragReference dragRef = session->GetDragAndDrop(ev)->GetDragReference(ev);
  1407.  
  1408.         TOffsetRange curSelectionRange;
  1409.         _fTextension->GetSelectionRange(&curSelectionRange);
  1410.         
  1411.         HideDragHilite(dragRef);
  1412.  
  1413.         if ( _fDragData->dropPoint.Start() == -1 ||
  1414.              ((dragAttributes & kODDropIsInSourceFrame) &&
  1415.               _fDragData->dropPoint.Start() >= curSelectionRange.Start() &&
  1416.               _fDragData->dropPoint.Start() <= curSelectionRange.End()) )
  1417.         {
  1418.             // Item is being dropped inside the original selection
  1419.             
  1420.             result = kODDropFail;
  1421.         }
  1422.         else
  1423.         {
  1424.             // Determine the nature of the drag (copy vs. move).
  1425.             if ( dragAttributes & kODDropIsMove ) 
  1426.                 result = kODDropMove;
  1427.             else if ( dragAttributes & kODDropIsCopy ) 
  1428.                 result = kODDropCopy;
  1429.             else if ( dragAttributes & kODDropIsPasteAs ) 
  1430.                 result = kODDropMove;    // Since we don't handle Paste As.
  1431.             
  1432.             ODBoolean textensionInactive = kODFalse;
  1433.             if ( !facet->GetWindow(ev)->IsActive(ev) )
  1434.             {
  1435.                 textensionInactive = kODTrue;
  1436.                 _fTextension->Activate(kODTrue);
  1437.             }
  1438.             
  1439.             // Suspend drawing until all mangling is complete.
  1440.             CTextensionDisplay* display = _fTextension->GetDisplayHandler();
  1441.             display->DisableDrawing();
  1442.         
  1443.             TRY
  1444.                 if ( result == kODDropMove && (dragAttributes & kODDragIsInSourceFrame) )
  1445.                 {
  1446.                     // The item is being dropped in the source frame, thus signifying
  1447.                     // a "move". So we first remove the original data.
  1448.                     somSelf->DoClear(ev, frame);
  1449.                     
  1450.                     // Adjust the drop range. Removing the old "current" selection may cause
  1451.                     // things to move.
  1452.                     if ( _fDragData->dropPoint.Start() >= curSelectionRange.End() )
  1453.                     {
  1454.                         long newStart = _fDragData->dropPoint.Start() - 
  1455.                                             (curSelectionRange.End() - curSelectionRange.Start());
  1456.                 
  1457.                         _fDragData->dropPoint.Set(newStart, newStart, false, true);
  1458.                     }
  1459.                 }
  1460.                 
  1461.                 // We use -1 to denote an empty document but Textension doesn't like
  1462.                 // negative numbers. So I am setting the "selection" range to a valid
  1463.                 // value.
  1464.                 if ( _fDragData->dropPoint.Start() == -1 )
  1465.                      _fDragData->dropPoint.Set(0L, 1L, false, true);
  1466.                 
  1467.                 // Read in the data from each of the Drag & Drop StorageUnits.
  1468.                 for (ODStorageUnit* dragSU = dropInfo->First(ev); dragSU; dragSU = dropInfo->Next(ev))
  1469.                 {
  1470.                     // If its something we can internalize, do so.
  1471.                     if ( dragSU->Exists(ev, kODPropContents, kTextEditorKind, 0)    
  1472.                       || dragSU->Exists(ev, kODPropContents, gGlobals->fScrapTextValue, 0)
  1473.                       || dragSU->Exists(ev, kODPropContents, gGlobals->fTextFileValue, 0) )
  1474.                     {
  1475.                         ODULong bytesRead = somSelf->InternalizeContent(ev, dragSU, 
  1476.                                                                         &_fDragData->dropPoint);
  1477.  
  1478.                         if ( bytesRead > 0 )
  1479.                             somSelf->HandleChange(ev);
  1480.                     }
  1481.                     else
  1482.                     // Otherwise, translate.
  1483.                     {
  1484.                         dragSU->Focus(ev, kODPropContents, kODPosUndefined, kODNULL, 1, kODPosUndefined);
  1485.                         TempODValueType foreignDataType = dragSU->GetType(ev);
  1486.                         
  1487.                         if ( session->GetTranslation(ev)->CanTranslate(ev, foreignDataType) == kODCanTranslate )
  1488.                         {
  1489.                             ODBoolean successful = somSelf->TranslateForeignData(ev, dragSU);
  1490.                             
  1491.                             if ( successful )
  1492.                                 somSelf->HandleChange(ev);
  1493.                         }
  1494.                     }
  1495.  
  1496.                     // Set up the selection to include the just-dragged-in area.
  1497.                     {
  1498.                         TOffsetRange dragEnd;
  1499.                         _fTextension->GetSelectionRange(&dragEnd);
  1500.  
  1501.                         long newStart = _fDragData->dropPoint.Start();
  1502.                         long newEnd = dragEnd.Start();
  1503.                         
  1504.                         _fDragData->dropPoint.Set(newStart, newEnd, false, true);
  1505.                         _fTextension->SetSelectionRange(_fDragData->dropPoint);
  1506.                     }
  1507.                 }
  1508.             CATCH_ALL
  1509.                 // Done mangling the text. Force update.
  1510.                 display->EnableDrawing();
  1511.                 display->InvalidDraw();
  1512.                 RERAISE;
  1513.             ENDTRY
  1514.             
  1515.             // Done mangling the text. Force update.
  1516.             display->EnableDrawing();
  1517.             display->InvalidDraw();
  1518.             
  1519.            { 
  1520.                 // Force everthing to redraw.
  1521.                 ODRect    bounds;
  1522.                 Rect    viewRect;
  1523.                 
  1524.                 _fTextension->GetViewRect(&viewRect);
  1525.                 IntToFixedRect(viewRect, bounds);
  1526.                 
  1527.                 TempODShape invalidArea = frame->CreateShape(ev);
  1528.                 invalidArea->SetRectangle(ev, &bounds);
  1529.                 facet->Invalidate(ev, invalidArea, kODNULL);
  1530.             }
  1531.             
  1532.             somSelf->AdjustScrollbars(ev, frame);
  1533.             
  1534.             if ( textensionInactive )
  1535.                 _fTextension->Activate(kODFalse);
  1536.         }
  1537.     
  1538.         // If the drag didn't originate with us, we clean up the temporary
  1539.         // drag structure here.
  1540.         
  1541.         if ( _fDragData->originator == kODNULL )
  1542.         {
  1543.             ODDeleteObject(_fDragData);
  1544.             _fDragData = kODNULL;
  1545.         }
  1546.  
  1547.     SOM_CATCH_ALL
  1548.     
  1549.         result = kODDropFail;
  1550.     
  1551.         // If the drag didn't originate with us, we clean up the temporary
  1552.         // drag structure here.
  1553.         
  1554.         if ( _fDragData->originator == kODNULL )
  1555.         {
  1556.             ODDeleteObject(_fDragData);
  1557.             _fDragData = kODNULL;
  1558.         }
  1559.  
  1560.     SOM_ENDTRY
  1561.  
  1562.     return result;
  1563. }
  1564.  
  1565.  
  1566.  
  1567. //==============================================================================
  1568. #pragma mark    • Undo •
  1569. //==============================================================================
  1570.  
  1571. //------------------------------------------------------------------------------
  1572. // Method:        UndoAction
  1573. // Origin:        ODPart
  1574. //------------------------------------------------------------------------------
  1575. SOM_Scope    void  
  1576. SOMLINK        TextEditor__UndoAction
  1577.             (
  1578.                 SampleCode_TextEditor*        somSelf, 
  1579.                 Environment*                ev,
  1580.                 ODActionData*                actionState
  1581.             )
  1582. {
  1583.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1584.     SOMMethodDebug("TextEditor","UndoAction");
  1585.  
  1586.     SOM_TRY
  1587.     
  1588.         THROW(kODErrNotImplemented);
  1589.     
  1590.     SOM_CATCH_ALL
  1591.     SOM_ENDTRY
  1592. }
  1593.  
  1594. //------------------------------------------------------------------------------
  1595. // Method:        RedoAction
  1596. // Origin:        ODPart
  1597. //------------------------------------------------------------------------------
  1598. SOM_Scope    void  
  1599. SOMLINK        TextEditor__RedoAction
  1600.             (
  1601.                 SampleCode_TextEditor*        somSelf, 
  1602.                 Environment*                ev,
  1603.                 ODActionData*                actionState
  1604.             )
  1605. {
  1606.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1607.     SOMMethodDebug("TextEditor","RedoAction");
  1608.  
  1609.     SOM_TRY
  1610.     
  1611.         THROW(kODErrNotImplemented);
  1612.     
  1613.     SOM_CATCH_ALL
  1614.     SOM_ENDTRY
  1615. }
  1616.  
  1617. //------------------------------------------------------------------------------
  1618. // Method:        DisposeActionState
  1619. // Origin:        ODPart
  1620. //------------------------------------------------------------------------------
  1621. SOM_Scope    void  
  1622. SOMLINK        TextEditor__DisposeActionState
  1623.             (
  1624.                 SampleCode_TextEditor*        somSelf, 
  1625.                 Environment*                ev,
  1626.                 ODActionData*                actionState,
  1627.                 ODDoneState                    doneState
  1628.             )
  1629. {
  1630.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1631.     SOMMethodDebug("TextEditor","DisposeActionState");
  1632.  
  1633.     SOM_TRY
  1634.     
  1635.         THROW(kODErrNotImplemented);
  1636.     
  1637.     SOM_CATCH_ALL
  1638.     SOM_ENDTRY
  1639. }
  1640.  
  1641. //------------------------------------------------------------------------------
  1642. // Method:        WriteActionState
  1643. // Origin:        ODPart
  1644. //------------------------------------------------------------------------------
  1645. SOM_Scope    void  
  1646. SOMLINK        TextEditor__WriteActionState
  1647.             (
  1648.                 SampleCode_TextEditor*        somSelf, 
  1649.                 Environment*                ev,
  1650.                 ODActionData*                actionState,
  1651.                 ODStorageUnitView*            storageUnitView
  1652.             )
  1653. {
  1654.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1655.     SOMMethodDebug("TextEditor","WriteActionState");
  1656.  
  1657.     SOM_TRY
  1658.     
  1659.         THROW(kODErrNotImplemented);
  1660.     
  1661.     SOM_CATCH_ALL
  1662.     SOM_ENDTRY
  1663. }
  1664.  
  1665. //------------------------------------------------------------------------------
  1666. // Method:        ReadActionState
  1667. // Origin:        ODPart
  1668. //------------------------------------------------------------------------------
  1669. SOM_Scope    ODActionData  
  1670. SOMLINK        TextEditor__ReadActionState
  1671.             (
  1672.                 SampleCode_TextEditor*        somSelf, 
  1673.                 Environment*                ev,
  1674.                 ODStorageUnitView*            storageUnitView
  1675.             )
  1676. {
  1677.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1678.     SOMMethodDebug("TextEditor","ReadActionState");
  1679.  
  1680.     ODActionData data;
  1681.     data._maximum = 0;
  1682.     data._length = 0;
  1683.     data._buffer = kODNULL;
  1684.     
  1685.     SOM_TRY
  1686.     
  1687.         THROW(kODErrNotImplemented);
  1688.     
  1689.     SOM_CATCH_ALL
  1690.     SOM_ENDTRY
  1691.  
  1692.     return data;
  1693. }
  1694.  
  1695. //==============================================================================
  1696. #pragma mark    -
  1697. //==============================================================================
  1698.  
  1699. //==============================================================================
  1700. #pragma mark    • Event Handling •
  1701. //==============================================================================
  1702.  
  1703. //------------------------------------------------------------------------------
  1704. // Method:        MakeSelectionVisible
  1705. // Origin:        TextEditor
  1706. //
  1707. // Description:    Assure that the end of the pasted selection is in the frame.
  1708. //------------------------------------------------------------------------------
  1709.  
  1710. SOM_Scope    void
  1711. SOMLINK        TextEditor__MakeSelectionVisible
  1712.             (
  1713.                 SampleCode_TextEditor*        somSelf,
  1714.                 Environment*                ev,
  1715.                 ODFrame*                    frame
  1716.             )
  1717. {
  1718.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1719.     SOMMethodDebug("TextEditor","MakeSelectionVisible");
  1720.     
  1721.     SOM_TRY
  1722.  
  1723.         // Assure that the end of the selection is in the frame.
  1724.         
  1725.         if ( frame->IsRoot(ev) )
  1726.         {            
  1727.             short editAction = _fTextension->GetLastEditAction();
  1728.     
  1729.             ODBoolean needAdjustScrollbars = (editAction & kScrollSelection) != 0;
  1730.             if ( editAction & kScrollSelection )
  1731.             {
  1732.                 Rect visRect;
  1733.                 _fTextension->GetViewRect(&visRect);
  1734.                 
  1735.                 TLongPoint scrollVals;
  1736.                 if ( !_fTextension->IsSelectionVisible(visRect, &scrollVals) )
  1737.                 {
  1738.                     _fTextension->Scroll(&scrollVals);
  1739.                         
  1740.                     // This part, especially, should only be done if it's a root frame.
  1741.                     ODFacet* facet = somSelf->GetActiveFacetForFrame(ev, frame);
  1742.                     CFocus intiateDrawing(ev, facet);
  1743.                     somSelf->DrawPageBounds(ev);
  1744.                 
  1745.                     needAdjustScrollbars = kODTrue;
  1746.                 }
  1747.             }
  1748.             
  1749.             // We might need to adjust the scrollbars whenever this routine 
  1750.             // is called.  Textension will tell us when we need to do this.
  1751.             if ( needAdjustScrollbars )
  1752.                 somSelf->AdjustScrollbars(ev, frame);
  1753.         }
  1754.  
  1755.     SOM_CATCH_ALL
  1756.     SOM_ENDTRY
  1757. }
  1758.  
  1759. //------------------------------------------------------------------------------
  1760. // Method:        NotDragSelection
  1761. // Origin:        TextEditor
  1762. //------------------------------------------------------------------------------
  1763.  
  1764. SOM_Scope    ODBoolean
  1765. SOMLINK        TextEditor__NotDragSelection
  1766.             (
  1767.                 SampleCode_TextEditor*        somSelf,
  1768.                 Environment*                ev,
  1769.                 ODFacet*                    facet,
  1770.                 Point*                        where,
  1771.                 ODEventData*                event
  1772.             )
  1773. {
  1774.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1775.     SOMMethodDebug("TextEditor","NotDragSelection");
  1776.  
  1777.     ODBoolean notDragging = kODTrue;
  1778.     
  1779.     SOM_TRY
  1780.     
  1781.         somSelf->CalcSelectionRgn(ev, facet);
  1782.         
  1783.         if ( PtInRgn(*where, (RgnHandle) _fSelectionRgn) && 
  1784.              WaitMouseMoved(event->where) )
  1785.         {
  1786.             notDragging = kODFalse;
  1787.         }
  1788.         
  1789.     SOM_CATCH_ALL
  1790.     
  1791.         notDragging = kODTrue;
  1792.     
  1793.     SOM_ENDTRY
  1794.  
  1795.     return notDragging;
  1796. }
  1797.  
  1798. //------------------------------------------------------------------------------
  1799. // Method:        DoMouseEvent
  1800. // Origin:        TextEditor
  1801. //------------------------------------------------------------------------------
  1802.  
  1803. SOM_Scope    void
  1804. SOMLINK        TextEditor__DoMouseEvent
  1805.             (
  1806.                 SampleCode_TextEditor*        somSelf,
  1807.                 Environment*                ev,
  1808.                 ODFacet*                    facet,
  1809.                 Point*                        where,
  1810.                 ODEventData*                event
  1811.             )
  1812. {
  1813.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1814.     SOMMethodDebug("TextEditor","DoMouseEvent");
  1815.  
  1816.     SOM_TRY
  1817.  
  1818.         // Determine if it was a hit on one of our scroll bars.
  1819.         ODSShort partCode = 0;
  1820.         ControlHandle scrollbar = kODNULL;
  1821.         {
  1822.             WindowPtr window = facet->GetCanvas(ev)->GetQDPort(ev);
  1823.             partCode = FindControl(*where, window, &scrollbar);
  1824.             
  1825.             // Make sure it's a control that belongs to us.
  1826.             if ( scrollbar != _fVScrollbar && scrollbar != _fHScrollbar )
  1827.                 partCode = 0;
  1828.         }
  1829.         
  1830.         // Handle it.
  1831.         if ( partCode > 0 )
  1832.         {
  1833.             somSelf->DoScrollDocument(ev, facet, where, partCode, scrollbar);
  1834.         }
  1835.         else if ( somSelf->NotDragSelection(ev, facet, where, event) )
  1836.         {
  1837.             // Click in document (activate if background click).
  1838.             
  1839.             if ( event->what == kODEvtBGMouseDown )
  1840.             {
  1841.                 somSelf->Activate(ev, facet);
  1842.             }
  1843.             else
  1844.             {        
  1845.                 ODFrame* frame = facet->GetFrame(ev);
  1846.  
  1847.                 ClickCommandInfo    info;
  1848.                 ScrollDataRec*        scrollData = kODNULL;
  1849.                 ClickLoopProcPtr    clickLoop = kODNULL;
  1850.                 TempODPtr            disposer = kODNULL;
  1851.                 
  1852.                 if ( frame->IsRoot(ev) )
  1853.                 {
  1854.                     scrollData = new ScrollDataRec;
  1855.                        disposer = scrollData;
  1856.                     
  1857.                     scrollData->vScrollbar = _fVScrollbar;
  1858.                     scrollData->hScrollbar = _fHScrollbar;
  1859.                     scrollData->frame      = frame;
  1860.                     scrollData->textension = kODNULL;
  1861.                     scrollData->textEditor = somSelf;
  1862.                     
  1863.                     clickLoop = (ClickLoopProcPtr) &ClickLoopProc;
  1864.                 }
  1865.         
  1866.                 CFocus initiateDrawing(ev, facet);
  1867.         
  1868.                 _fTextension->Click(*event, &info, clickLoop, (void*) scrollData);
  1869.                 
  1870.                 if ( frame->IsRoot(ev) )
  1871.                     somSelf->DrawPageBounds(ev);
  1872.             }
  1873.         }
  1874.         else
  1875.         {
  1876.             somSelf->DoDragSelection(ev, event, facet);
  1877.         }
  1878.  
  1879.     SOM_CATCH_ALL
  1880.     SOM_ENDTRY
  1881. }
  1882.  
  1883. //------------------------------------------------------------------------------
  1884. // Method:        DoScrollDocument
  1885. // Origin:        TextEditor
  1886. //------------------------------------------------------------------------------
  1887.  
  1888. SOM_Scope    void
  1889. SOMLINK        TextEditor__DoScrollDocument
  1890.              (
  1891.                 SampleCode_TextEditor*        somSelf,
  1892.                 Environment*                ev,
  1893.                 ODFacet*                    facet,
  1894.                  Point*                        mouse,
  1895.                 ODSShort                    partCode,
  1896.                 ControlHandle                scrollbar
  1897.             )
  1898. {
  1899.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1900.     SOMMethodDebug("TextEditor","DoScrollDocument");
  1901.  
  1902.     SOM_TRY
  1903.     
  1904.         ODFrame* frame = facet->GetFrame(ev);
  1905.     
  1906.         if ( partCode == kControlIndicatorPart )
  1907.         {
  1908.             short vScroll = GetControlValue(_fVScrollbar);
  1909.             short hScroll = GetControlValue(_fHScrollbar);
  1910.             
  1911.             TrackControl(scrollbar, *mouse, kODNULL);
  1912.             
  1913.             vScroll -= GetControlValue(_fVScrollbar);
  1914.             hScroll -= GetControlValue(_fHScrollbar);
  1915.             
  1916.             TLongPoint scrollAmount(hScroll, vScroll);
  1917.             _fTextension->Scroll(&scrollAmount);
  1918.         }
  1919.         else
  1920.         {
  1921.             ControlActionUPP scrollProcUPP = NewControlActionProc(ScrollProc);
  1922.             ScrollDataRec* scrollData = (ScrollDataRec*) ODNewPtr(sizeof(ScrollDataRec));
  1923.             
  1924.             scrollData->vScrollbar = _fVScrollbar;
  1925.             scrollData->hScrollbar = _fHScrollbar;
  1926.             scrollData->frame = frame;
  1927.             scrollData->textension = _fTextension;
  1928.             scrollData->textEditor = somSelf;
  1929.             
  1930.             SetControlReference(scrollbar, (long) scrollData);
  1931.                 // Stuff the scroll data structure into the scroll bar we are 
  1932.                 // working with.
  1933.     
  1934.             TrackControl(scrollbar, *mouse, scrollProcUPP);
  1935.         }
  1936.  
  1937.         if ( frame->IsRoot(ev) )
  1938.         {
  1939.             CFocus intiateDrawing(ev, facet);
  1940.             somSelf->DrawPageBounds(ev);
  1941.         }
  1942.  
  1943.     SOM_CATCH_ALL
  1944.     SOM_ENDTRY
  1945. }
  1946.  
  1947. //------------------------------------------------------------------------------
  1948. // Method:        DoDragSelection
  1949. // Origin:        TextEditor
  1950. //------------------------------------------------------------------------------
  1951.  
  1952. SOM_Scope    void
  1953. SOMLINK        TextEditor__DoDragSelection
  1954.             (
  1955.                 SampleCode_TextEditor*        somSelf,
  1956.                 Environment*                ev,
  1957.                 ODEventData*                event,
  1958.                 ODFacet*                    facet
  1959.             )
  1960. {
  1961.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  1962.     SOMMethodDebug("TextEditor","DoDragSelection");
  1963.  
  1964.     SOM_TRY
  1965.  
  1966.         TOffsetRange     curSelectionRange;
  1967.         ODDropResult    result = kODDropFail;
  1968.         TempODPart        part = kODNULL;
  1969.         ODFrame*        frame = facet->GetFrame(ev);
  1970.         
  1971.         _fTextension->GetSelectionRange(&curSelectionRange);
  1972.             // Get the selection range to written out.
  1973.         
  1974.         ODDragAndDrop* dragdrop = ODGetSession(ev, somSelf)->GetDragAndDrop(ev);
  1975.         
  1976.         dragdrop->Clear(ev);
  1977.             // Remove existing data from the drag container.
  1978.         
  1979.         ODStorageUnit* dragdropSU = dragdrop->GetContentStorageUnit(ev);
  1980.         
  1981.         somSelf->CheckAndAddProperties(ev, dragdropSU);
  1982.             // Add the properties we need to successfully externalize
  1983.             // ourselves into the destination storage unit.
  1984.         
  1985.         // Write out the part's state information.
  1986.         ODDraft* toDraft = ODGetDraft(ev, dragdropSU);
  1987.         ODDraft* fromDraft = ODGetDraft(ev, somSelf);
  1988.     
  1989.         // The clone type (cut or copy) should depend on whether the document
  1990.         // is read-only. (i.e. a read-only document must use kODCloneCopy -- a 
  1991.         // r/w document must use kODCloneCut if it wants to support kODDropMove).
  1992.         ODCloneKind method = (_fReadOnlyStorage ? kODCloneCopy  
  1993.                                                 : kODCloneCut);
  1994.         
  1995.         ODDraftKey key = fromDraft->BeginClone(ev, toDraft, kODNULL, method);
  1996.  
  1997.         TRY
  1998.             somSelf->ExternalizeStateInfo(ev, dragdropSU, key, frame);
  1999.                 
  2000.             // Write out the current selection.
  2001.             somSelf->ExternalizeContent(ev, dragdropSU, &curSelectionRange);
  2002.     
  2003.             fromDraft->EndClone(ev, key);
  2004.             
  2005.         CATCH_ALL
  2006.             // TextEditor: Clone to drag-and-drop container failed
  2007.             fromDraft->AbortClone(ev, key);
  2008.             RERAISE;
  2009.         ENDTRY
  2010.                 
  2011.         // Create and init our drag state structure to be used by
  2012.         // DragEnter, DragWithin, DragLeave, and Drop
  2013.     
  2014.         TOffsetRange blankRange((long) -1, (long) 0);
  2015.     
  2016.         _fDragData = new DragData;
  2017.         
  2018.         _fDragData->dropPoint  = blankRange;
  2019.         _fDragData->acceptable = kUndefined;
  2020.         _fDragData->originator = facet;
  2021.         
  2022.         // Move selection region into global coordinates
  2023.         Point pt = {0,0};
  2024.         {
  2025.             CFocus initiateDrawing(ev, facet);
  2026.             LocalToGlobal(&pt);
  2027.         }
  2028.         
  2029.         OffsetRgn((RgnHandle) _fSelectionRgn, pt.h, pt.v);
  2030.         
  2031.         // $$$$$ Undo support for dragging goes in here somewhere!!
  2032.         
  2033.         RgnHandle dragRgn = ODNewRgn();
  2034.  
  2035.         TRY
  2036.             CopyRgn((RgnHandle) _fSelectionRgn, dragRgn);
  2037.             InsetRgn(dragRgn, -1, -1);
  2038.             DiffRgn(dragRgn, (RgnHandle) _fSelectionRgn, dragRgn);
  2039.             
  2040.             // Create Byte Arrays for the 2 dynamic parameters
  2041.             {
  2042.                 TempODByteArrayStruct dragRgnBA = CreateByteArrayStruct(&dragRgn, sizeof(RgnHandle));
  2043.                 TempODByteArrayStruct eventBA = CreateByteArrayStruct(&event, sizeof(ODEventData*));
  2044.                 
  2045.                 ODPart* returnPart;
  2046.                 result = dragdrop->StartDrag(ev, frame, kODDragImageRegionHandle, dragRgnBA, 
  2047.                                              &returnPart, eventBA);
  2048.                 part = returnPart;        // Put it into our TempODPart
  2049.             }
  2050.             
  2051.             // Handle drop result.
  2052.             if ( result == kODDropMove )
  2053.             {
  2054.                 // If we're dropping into our own part, we'll handle the clearing
  2055.                 // of the old selection in our Drop code, so don't do it here (because
  2056.                 // the selection will now be the dropped data).
  2057.                 if ( !ODObjectsAreEqual(ev, _fSelf, part) )
  2058.                 {
  2059.                     // Remove the dragged content.
  2060.                     somSelf->DoClear(ev, frame);
  2061.                 }
  2062.             }
  2063.             else if ( result == kODDropFail )
  2064.             {
  2065.                 CFocus initiateDrawing(ev, facet);
  2066.         
  2067.                 // Restore the "old" selection if the drop failed
  2068.                 _fTextension->SetSelectionRange(curSelectionRange, kODFalse, kODTrue);
  2069.             }
  2070.         CATCH_ALL
  2071.             DisposeRgn(dragRgn);
  2072.             ODDeleteObject(_fDragData);
  2073.             _fDragData = kODNULL;
  2074.             RERAISE;
  2075.         ENDTRY
  2076.         
  2077.         DisposeRgn(dragRgn);
  2078.         ODDeleteObject(_fDragData);
  2079.         _fDragData = kODNULL;
  2080.         
  2081.     SOM_CATCH_ALL
  2082.     SOM_ENDTRY
  2083. }
  2084.  
  2085. //------------------------------------------------------------------------------
  2086. // Method:        DoCut
  2087. // Origin:        TextEditor
  2088. //------------------------------------------------------------------------------
  2089.  
  2090. SOM_Scope    void  
  2091. SOMLINK        TextEditor__DoCut
  2092.             (
  2093.                 SampleCode_TextEditor*        somSelf, 
  2094.                 Environment*                ev,
  2095.                 ODFrame*                    frame
  2096.             )
  2097. {
  2098.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2099.     SOMMethodDebug("TextEditor","DoCut");
  2100.  
  2101.     SOM_TRY
  2102.     
  2103.         // $$$$$ should be using kODCloneCut and our own code...
  2104.     
  2105.         somSelf->DoCopy(ev, frame);
  2106.         somSelf->DoClear(ev, frame);
  2107.     
  2108.         somSelf->MakeSelectionVisible(ev, frame);
  2109.  
  2110.     SOM_CATCH_ALL
  2111.     SOM_ENDTRY
  2112. }
  2113.  
  2114. //------------------------------------------------------------------------------
  2115. // Method:        DoCopy
  2116. // Origin:        TextEditor
  2117. //------------------------------------------------------------------------------
  2118.  
  2119. SOM_Scope    void  
  2120. SOMLINK        TextEditor__DoCopy
  2121.             (
  2122.                 SampleCode_TextEditor*        somSelf, 
  2123.                 Environment*                ev,
  2124.                 ODFrame*                    frame
  2125.             )
  2126. {
  2127.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2128.     SOMMethodDebug("TextEditor","DoCopy");
  2129.  
  2130.     SOM_TRY
  2131.         
  2132.         TOffsetRange curSelectionRange;
  2133.         
  2134.         ODSession* session = ODGetSession(ev, somSelf);
  2135.         
  2136.         // Acquire clipboard focus
  2137.         session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fClipboardFocus, frame);
  2138.         
  2139.         _fTextension->GetSelectionRange(&curSelectionRange);
  2140.             // Get the selection range to written out.
  2141.         
  2142.         ODClipboard* clipboard = session->GetClipboard(ev);
  2143.         
  2144.         clipboard->Clear(ev);
  2145.             // Remove existing data from the clipboard.
  2146.         
  2147.         ODStorageUnit*    clipboardSU = clipboard->GetContentStorageUnit(ev);
  2148.         ODDraft*        fromDraft   = ODGetDraft(ev, somSelf); 
  2149.         ODDraft*        toDraft     = ODGetDraft(ev, clipboardSU);
  2150.         
  2151.         TRY
  2152.             // Add the properties we need to successfully externalize
  2153.             // ourselves into the destination storage unit.
  2154.             somSelf->CheckAndAddProperties(ev, clipboardSU);
  2155.                         
  2156.             ODDraftKey key = fromDraft->BeginClone(ev, toDraft, kODNULL, kODCloneCopy);
  2157.             TRY
  2158.                 somSelf->ExternalizeStateInfo(ev, clipboardSU, key, frame);
  2159.                     // Write out the part's state information.
  2160.                 
  2161.                 somSelf->ExternalizeContent(ev, clipboardSU, &curSelectionRange);
  2162.                     // Write out the current selection.
  2163.                 
  2164.                 fromDraft->EndClone(ev, key);
  2165.             CATCH_ALL
  2166.                 fromDraft->AbortClone(ev, key);
  2167.                 RERAISE;
  2168.             ENDTRY
  2169.         CATCH_ALL
  2170.             clipboard->Clear(ev);
  2171.             RERAISE;
  2172.         ENDTRY
  2173.         
  2174.     SOM_CATCH_ALL
  2175.     SOM_ENDTRY
  2176.  
  2177. }
  2178.  
  2179. //------------------------------------------------------------------------------
  2180. // Method:        DoPaste
  2181. // Origin:        TextEditor
  2182. //------------------------------------------------------------------------------
  2183.  
  2184. SOM_Scope    void  
  2185. SOMLINK        TextEditor__DoPaste
  2186.             (
  2187.                 SampleCode_TextEditor*        somSelf, 
  2188.                 Environment*                ev,
  2189.                 ODFrame*                    frame
  2190.             )
  2191. {
  2192.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2193.     SOMMethodDebug("TextEditor","DoPaste");
  2194.  
  2195.     SOM_TRY
  2196.  
  2197.         // $$$$$ UNDO: capture current selection
  2198.         
  2199.         // Get the selection range.
  2200.         TOffsetRange curSelectionRange;
  2201.         _fTextension->GetSelectionRange(&curSelectionRange);
  2202.         
  2203.         ODSession* session = ODGetSession(ev, frame);
  2204.         
  2205.         if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fClipboardFocus, 
  2206.                                                       frame) )
  2207.         {
  2208.             ODULong            bytesRead = 0;
  2209.             ODClipboard*    clipboard = session->GetClipboard(ev);
  2210.             ODFacet*        facet     = somSelf->GetActiveFacetForFrame(ev, frame);
  2211.             
  2212.             CFocus intiateDrawing(ev, facet);
  2213.         
  2214.             // Read in the clipboard data replacing the current selection.
  2215.             bytesRead = somSelf->InternalizeContent(ev, clipboard->GetContentStorageUnit(ev), 
  2216.                                                     &curSelectionRange);
  2217.     
  2218.             session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fClipboardFocus, 
  2219.                                                         frame);
  2220.     
  2221.             if ( bytesRead > 0 )
  2222.             {
  2223.                 somSelf->HandleChange(ev);
  2224.                 somSelf->MakeSelectionVisible(ev, frame);
  2225.             }
  2226.         }
  2227.  
  2228.     SOM_CATCH_ALL
  2229.     SOM_ENDTRY
  2230. }
  2231.  
  2232. //------------------------------------------------------------------------------
  2233. // Method:        DoPasteAs
  2234. // Origin:        TextEditor
  2235. //------------------------------------------------------------------------------
  2236.  
  2237. SOM_Scope    void  
  2238. SOMLINK        TextEditor__DoPasteAs
  2239.             (
  2240.                 SampleCode_TextEditor*        somSelf, 
  2241.                 Environment*                ev,
  2242.                 ODFrame*                    frame
  2243.             )
  2244. {
  2245.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2246.     SOMMethodDebug("TextEditor","DoPasteAs");
  2247.  
  2248.     SOM_TRY
  2249.  
  2250.         // $$$$$ UNDO: capture current selection
  2251.         
  2252.         // Get the selection range.
  2253.         TOffsetRange curSelectionRange;
  2254.         _fTextension->GetSelectionRange(&curSelectionRange);
  2255.         
  2256.         ODSession* session = ODGetSession(ev, frame);
  2257.         
  2258.         if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fClipboardFocus, frame) )
  2259.         {
  2260.             ODULong            bytesRead = 0;
  2261.             ODClipboard*    clipboard = session->GetClipboard(ev);
  2262.             ODFacet*        facet = somSelf->GetActiveFacetForFrame(ev, frame);
  2263.             ODPasteAsResult    result;
  2264.             
  2265.             CFocus intiateDrawing(ev, facet);
  2266.         
  2267.             if ( clipboard->ShowPasteAsDialog(ev, kODFalse, kODPasteAsMergeOnly,
  2268.                                                 facet, gGlobals->fFrameView, &result) )
  2269.             {
  2270.                 ODDraft*        draft = ODGetDraft(ev, frame);
  2271.                 ODStorageUnit*    contentSU = clipboard->GetContentStorageUnit(ev);
  2272.                 
  2273.                 ODStorageUnit*    tempSU = kODNULL;
  2274.                 ODVolatile(tempSU);
  2275.                 
  2276.                 TRY
  2277.                     // Create a temporary buffer (su) for the translated data.
  2278.                     tempSU = draft->CreateStorageUnit(ev);
  2279.                     
  2280.                     // Translate the data.
  2281.                     TranslateData(ev, contentSU, tempSU, result.translateKind, result.selectedKind);
  2282.                 
  2283.                     // Read in the clipboard data replacing the current selection.
  2284.                     bytesRead = somSelf->InternalizeContent(ev, tempSU, &curSelectionRange);
  2285.                     
  2286.                     if ( tempSU )
  2287.                         draft->RemoveStorageUnit(ev, tempSU);
  2288.                     
  2289.                 CATCH_ALL
  2290.                     if ( tempSU )
  2291.                         draft->RemoveStorageUnit(ev, tempSU);
  2292.                     
  2293.                     somSelf->DoDialogBox(ev, frame, kErrorBoxID, kErrTranslationFailed);
  2294.                     
  2295.                     // An error occurred, so don't dirty the document.
  2296.                     bytesRead = 0;
  2297.                 ENDTRY
  2298.             }
  2299.     
  2300.             session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fClipboardFocus, frame);
  2301.     
  2302.             if ( bytesRead > 0 )
  2303.             {
  2304.                 somSelf->HandleChange(ev);
  2305.                 somSelf->MakeSelectionVisible(ev, frame);
  2306.             }
  2307.         }
  2308.  
  2309.     SOM_CATCH_ALL
  2310.     SOM_ENDTRY
  2311. }
  2312.  
  2313. //------------------------------------------------------------------------------
  2314. // Method:        DoClear
  2315. // Origin:        TextEditor
  2316. //------------------------------------------------------------------------------
  2317.  
  2318. SOM_Scope    void  
  2319. SOMLINK        TextEditor__DoClear
  2320.             (
  2321.                 SampleCode_TextEditor*        somSelf, 
  2322.                 Environment*                ev,
  2323.                 ODFrame*                    frame
  2324.             )
  2325. {
  2326.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2327.     SOMMethodDebug("TextEditor","DoClear");
  2328.  
  2329.     SOM_TRY
  2330.  
  2331.         // $$$$$ UNDO: capture current selection
  2332.     
  2333.         CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
  2334.         CFocus initiateDrawing(ev, frameInfo->GetActiveFacet());
  2335.     
  2336.         _fTextension->Clear();
  2337.     
  2338.         somSelf->MakeSelectionVisible(ev, frame);
  2339.     
  2340.     SOM_CATCH_ALL
  2341.     SOM_ENDTRY
  2342. }
  2343.  
  2344. //------------------------------------------------------------------------------
  2345. // Method:        DoSelectAll
  2346. // Origin:        TextEditor
  2347. //------------------------------------------------------------------------------
  2348.  
  2349. SOM_Scope    void  
  2350. SOMLINK        TextEditor__DoSelectAll
  2351.             (
  2352.                 SampleCode_TextEditor*        somSelf, 
  2353.                 Environment*                ev,
  2354.                 ODFrame*                    frame
  2355.             )
  2356. {
  2357.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2358.     SOMMethodDebug("TextEditor","DoSelectAll");
  2359.  
  2360.     SOM_TRY
  2361.     
  2362.         TOffsetRange curSelectionRange(0, _fTextension->CountCharsBytes());
  2363.         
  2364.         CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
  2365.         CFocus initiateDrawing(ev, frameInfo->GetActiveFacet());
  2366.     
  2367.         _fTextension->SetSelectionRange(curSelectionRange, kODTrue, kODTrue);
  2368.  
  2369.     SOM_CATCH_ALL
  2370.     SOM_ENDTRY
  2371. }
  2372.  
  2373. //------------------------------------------------------------------------------
  2374. // Method:        DoPageSetup
  2375. // Origin:        TextEditor
  2376. //------------------------------------------------------------------------------
  2377.  
  2378. SOM_Scope    void  
  2379. SOMLINK        TextEditor__DoPageSetup
  2380.             (
  2381.                 SampleCode_TextEditor*        somSelf, 
  2382.                 Environment*                ev,
  2383.                 ODFrame*                    frame
  2384.             )
  2385. {
  2386.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2387.     SOMMethodDebug("TextEditor","DoPageSetup");
  2388. }
  2389.  
  2390. //------------------------------------------------------------------------------
  2391. // Method:        DoPrint
  2392. // Origin:        TextEditor
  2393. //------------------------------------------------------------------------------
  2394.  
  2395. SOM_Scope    void  
  2396. SOMLINK        TextEditor__DoPrint
  2397.             (
  2398.                 SampleCode_TextEditor*        somSelf, 
  2399.                 Environment*                ev,
  2400.                 ODFrame*                    frame
  2401.             )
  2402. {
  2403.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2404.     SOMMethodDebug("TextEditor","DoPrint");
  2405. }
  2406.  
  2407. //------------------------------------------------------------------------------
  2408. // Method:        DoUndo
  2409. // Origin:        TextEditor
  2410. //------------------------------------------------------------------------------
  2411.  
  2412. SOM_Scope    void  
  2413. SOMLINK        TextEditor__DoUndo
  2414.             (
  2415.                 SampleCode_TextEditor*        somSelf, 
  2416.                 Environment*                ev,
  2417.                 ODFrame*                    frame,
  2418.                 ODBoolean                    undo
  2419.             )
  2420. {
  2421.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2422.     SOMMethodDebug("TextEditor","DoUndo");
  2423.  
  2424.     SOM_TRY
  2425.  
  2426.         somSelf->MakeSelectionVisible(ev, frame);
  2427.  
  2428.     SOM_CATCH_ALL
  2429.     SOM_ENDTRY
  2430. }
  2431.  
  2432. //------------------------------------------------------------------------------
  2433. // Method:        DoPreferences
  2434. // Origin:        TextEditor
  2435. //------------------------------------------------------------------------------
  2436.  
  2437. SOM_Scope    void
  2438. SOMLINK        TextEditor__DoPreferences
  2439.             (
  2440.                 SampleCode_TextEditor*        somSelf,
  2441.                 Environment*                ev,
  2442.                 ODFrame*                    frame
  2443.             )
  2444. {
  2445.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2446.     SOMMethodDebug("TextEditor","DoPreferences");
  2447.  
  2448.     SOM_TRY
  2449.  
  2450.         ModalPreferencesDialog(ev, frame);
  2451.  
  2452.     SOM_CATCH_ALL
  2453.     SOM_ENDTRY
  2454. }
  2455.  
  2456. //------------------------------------------------------------------------------
  2457. // Method:        ShowHideRuler
  2458. // Origin:        TextEditor
  2459. //------------------------------------------------------------------------------
  2460.  
  2461. SOM_Scope    void
  2462. SOMLINK        TextEditor__ShowHideRuler
  2463.             (
  2464.                 SampleCode_TextEditor*        somSelf,
  2465.                 Environment*                ev,
  2466.                 ODFrame*                    frame
  2467.             )
  2468. {
  2469.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2470.     SOMMethodDebug("TextEditor","ShowHideRuler");
  2471. }
  2472.  
  2473. //------------------------------------------------------------------------------
  2474. // Method:        DoSettings
  2475. // Origin:        TextEditor
  2476. //------------------------------------------------------------------------------
  2477.  
  2478. SOM_Scope    void
  2479. SOMLINK        TextEditor__DoSettings
  2480.             (
  2481.                 SampleCode_TextEditor*        somSelf,
  2482.                 Environment*                ev,
  2483.                 ODFrame*                    frame
  2484.             )
  2485. {
  2486.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2487.     SOMMethodDebug("TextEditor","DoSettings");
  2488.  
  2489.     SOM_TRY
  2490.         Rect        margins = _fPageMargins;
  2491.         ODUShort    alignment = _fTextAlignment;
  2492.         ODBoolean    changed = kODFalse;
  2493.         
  2494.         ModalSettingsDialog(ev, frame, &margins, &alignment);
  2495.     
  2496.         if ( margins.top != _fPageMargins.top ||
  2497.              margins.left != _fPageMargins.left ||
  2498.              margins.bottom != _fPageMargins.bottom ||
  2499.              margins.right != _fPageMargins.right )
  2500.         {
  2501.             _fPageMargins = margins;
  2502.     
  2503.             somSelf->CalcTextBounds(ev, frame);
  2504.             changed = kODTrue;
  2505.         }
  2506.     
  2507.         if ( alignment != _fTextAlignment )
  2508.         {
  2509.             _fTextAlignment = alignment;
  2510.                     
  2511.             char just;
  2512.             
  2513.             switch ( alignment )
  2514.             {
  2515.                 case left: just = kLeftJust; break;
  2516.                 case center: just = kCenterJust; break;
  2517.                 case right: just = kRightJust; break;
  2518.                 case fulljustification: just = kFullJust; break;
  2519.                 default:
  2520.                     just = kLeftJust;
  2521.             }
  2522.                 
  2523.             AttrObjModifier    runModifier(kJustAttr, &just, 0L);
  2524.             TOffsetRange    curSelectionRange(0, _fTextension->CountCharsBytes());
  2525.             
  2526.             CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
  2527.             CFocus initiateDrawing(ev, frameInfo->GetActiveFacet());
  2528.         
  2529.             _fTextension->UpdateRangeRulers(curSelectionRange, runModifier);
  2530.             
  2531.             changed = kODTrue;
  2532.         }
  2533.         
  2534.         if ( changed )
  2535.             somSelf->HandleChange(ev);
  2536.     
  2537.         somSelf->AdjustScrollbars(ev, frame);
  2538.  
  2539.     SOM_CATCH_ALL
  2540.     SOM_ENDTRY
  2541. }
  2542.  
  2543.  
  2544. //------------------------------------------------------------------------------
  2545. // Method:        RealFontSizeMenu
  2546. // Origin:        TextEditor
  2547. //------------------------------------------------------------------------------
  2548.  
  2549. SOM_Scope    void
  2550. SOMLINK        TextEditor__RealFontSizeMenu
  2551.             (
  2552.                 SampleCode_TextEditor*        somSelf,
  2553.                 Environment*                ev,
  2554.                 ODUShort                    fontNum
  2555.             )
  2556. {
  2557.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2558.     SOMMethodDebug("TextEditor","RealFontSizeMenu");
  2559.  
  2560.     SOM_TRY
  2561.     
  2562.         MenuHandle sizeMenu = (MenuHandle) gGlobals->fMenuBar->GetMenu(ev, kSizeMenuID);
  2563.         
  2564.         SetItemStyle(sizeMenu, 1, (RealFont(fontNum, 9) ? outline : normal)); 
  2565.         SetItemStyle(sizeMenu, 2, (RealFont(fontNum,10) ? outline : normal)); 
  2566.         SetItemStyle(sizeMenu, 3, (RealFont(fontNum,12) ? outline : normal)); 
  2567.         SetItemStyle(sizeMenu, 4, (RealFont(fontNum,14) ? outline : normal)); 
  2568.         SetItemStyle(sizeMenu, 5, (RealFont(fontNum,18) ? outline : normal)); 
  2569.         SetItemStyle(sizeMenu, 6, (RealFont(fontNum,24) ? outline : normal)); 
  2570.         SetItemStyle(sizeMenu, 7, (RealFont(fontNum,36) ? outline : normal)); 
  2571.         SetItemStyle(sizeMenu, 8, (RealFont(fontNum,48) ? outline : normal)); 
  2572.         SetItemStyle(sizeMenu, 9, (RealFont(fontNum,72) ? outline : normal)); 
  2573.  
  2574.     SOM_CATCH_ALL
  2575.     SOM_ENDTRY
  2576. }
  2577.  
  2578.  
  2579. //------------------------------------------------------------------------------
  2580. // Method:        DoTextStyling
  2581. // Origin:        TextEditor
  2582. //------------------------------------------------------------------------------
  2583.  
  2584. SOM_Scope    ODBoolean
  2585. SOMLINK        TextEditor__DoTextStyling
  2586.             (
  2587.                 SampleCode_TextEditor*        somSelf,
  2588.                 Environment*                ev,
  2589.                 ODFrame*                    frame,
  2590.                 ODID                        command
  2591.             )
  2592. {
  2593.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2594.     SOMMethodDebug("TextEditor","DoTextStyling");
  2595.  
  2596.     SOM_TRY
  2597.     
  2598.         AttrId    attrModified;
  2599.         void*    attrData;
  2600.         ODSLong    attrInfo = 0;
  2601.         
  2602.         if ( command >= kBaseFontSizeCmdID && command <= kBaseFontSizeCmdID + 999 )
  2603.         {
  2604.             // Change Font Size
  2605.             
  2606.             ODSShort fontSize = command - kBaseFontSizeCmdID;
  2607.             
  2608.             if ( command == kOtherFontSizeCmdID )
  2609.             {
  2610.                 // Get the current font size of the selected text.
  2611.                 ODSLong value;
  2612.                 if ( _fTextension->GetContinuousRun()->GetAttributeValue(kFontSizeAttr, &value) )
  2613.                     fontSize = (value >> 16);
  2614.                 else
  2615.                     fontSize = -1;
  2616.                     
  2617.                 somSelf->DoOtherFontSize(ev, frame, &fontSize);
  2618.     
  2619.                 if ( fontSize == -1 ) return kODTrue;
  2620.                     // user canceled the "other size" dialog
  2621.             }        
  2622.             
  2623.             attrModified = kFontSizeAttr;
  2624.             attrData = (void*) &fontSize;
  2625.         }
  2626.         else if ( command >= kBaseFontStyleCmdID && command <= kBaseFontStyleCmdID + 999 )
  2627.         {
  2628.             // Change Font Style
  2629.             
  2630.             ODSLong fontStyle = (ODSLong)(command - kBaseFontStyleCmdID);
  2631.             
  2632.             attrModified = kFaceAttr;
  2633.             attrData = (void*) &fontStyle;
  2634.             attrInfo = kToggleFace;
  2635.         }
  2636.         else
  2637.         {
  2638.             // Change Font (maybe)
  2639.             
  2640.             ODUShort fontNum = command - kBaseFontCmdID;
  2641.             
  2642.             attrModified = kFontAttr;
  2643.             attrData = (void*) &fontNum;
  2644.             
  2645.             // Make sure
  2646.             Str255 fontName;
  2647.             GetFontName(fontNum,fontName);
  2648.             if ( *fontName == 0 )
  2649.                 return kODFalse;
  2650.         }
  2651.             
  2652.         AttrObjModifier    runModifier(attrModified, attrData, attrInfo);
  2653.         TOffsetRange    curSelectionRange;
  2654.         
  2655.         CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
  2656.         CFocus initiateDrawing(ev, frameInfo->GetActiveFacet());
  2657.     
  2658.         _fTextension->GetSelectionRange(&curSelectionRange);
  2659.         _fTextension->UpdateRangeRuns(curSelectionRange, runModifier);
  2660.         
  2661.         somSelf->AdjustScrollbars(ev, frame);
  2662.  
  2663.         somSelf->HandleChange(ev);
  2664.  
  2665.     SOM_CATCH_ALL
  2666.     SOM_ENDTRY
  2667.     
  2668.     return kODTrue;
  2669. }
  2670.  
  2671. //------------------------------------------------------------------------------
  2672. // Method:        DoOtherFontSize
  2673. // Origin:        TextEditor
  2674. //------------------------------------------------------------------------------
  2675.  
  2676. SOM_Scope    void
  2677. SOMLINK        TextEditor__DoOtherFontSize
  2678.             (
  2679.                 SampleCode_TextEditor*        somSelf,
  2680.                 Environment*                ev,
  2681.                 ODFrame*                    frame,
  2682.                 ODSShort*                    fontSize
  2683.             )
  2684. {
  2685.     SOM_TRY
  2686.  
  2687.         const ODUShort    kSizeField = 3;
  2688.         const ODUShort    kDefaultButtonHighlight = 6;
  2689.         
  2690.         short    iType;
  2691.         Handle    iHandle;
  2692.         Rect    iRect;
  2693.         short    itemHit;
  2694.         Str255    strValue;
  2695.         long    value;
  2696.         
  2697.         ODSession* session = ODGetSession(ev, frame);
  2698.         
  2699.         if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fModalFocus, frame) )
  2700.         {
  2701.             CUsingLibraryResources res;
  2702.             
  2703.             session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  2704.                 // Dim the frontmost document window.
  2705.             
  2706.             DialogPtr dialog = GetNewDialog(kOtherSizeDialogID, kODNULL, (WindowPtr)-1L);
  2707.             
  2708.             // Set dialog font and other std things.
  2709.             SetDialogDefaults(dialog, kDialogFontInfoID, kOtherFontIndex);
  2710.             
  2711.             // Install a default drawing routine for the "default" button highlighting.
  2712.             GetDialogItem(dialog, kDefaultButtonHighlight, &iType, &iHandle, &iRect);
  2713.             SetDialogItem(dialog, kDefaultButtonHighlight, iType, (Handle)GetODOutlineDefaultButtonDrawProc(), &iRect);
  2714.             
  2715.             // Stuff a default value into the size field.
  2716.             GetDialogItem(dialog, kSizeField, &iType, &iHandle, &iRect);
  2717.             {
  2718.                 Str255 startSizeStr = "\p";
  2719.                 if (*fontSize > 0)
  2720.                     NumToString(*fontSize, startSizeStr);
  2721.                 SetDialogItemText(iHandle, startSizeStr);
  2722.             }
  2723.             SelectDialogItemText(dialog, kSizeField, 0, 32767);
  2724.             
  2725.             ShowWindow(dialog);
  2726.             
  2727.             // Prepare a filter proc which only allows numbers [0-9] to be entered.
  2728.             ModalFilterUPP otherDialogProc = NewModalFilterProc(OtherDialogFilter);
  2729.             
  2730.             // Handle the dialog.
  2731.             do
  2732.             {
  2733.                 ModalDialog(otherDialogProc, &itemHit);
  2734.             }
  2735.             while ( itemHit != ok && itemHit != cancel );
  2736.             
  2737.             // Check the result.
  2738.             if ( itemHit == ok ) 
  2739.             {
  2740.                 GetDialogItemText(iHandle, strValue);
  2741.                 if (strValue[0] == 0)
  2742.                 {
  2743.                     *fontSize = -1;
  2744.                 }
  2745.                 else
  2746.                 {
  2747.                     StringToNum(strValue, &value);
  2748.                 
  2749.                     if ( value > 512 )
  2750.                         *fontSize = 512;
  2751.                     else if ( value <= 0 )
  2752.                         *fontSize = -1;
  2753.                     else 
  2754.                         *fontSize = (ODSShort) value;
  2755.                 }
  2756.             }
  2757.             else
  2758.             {
  2759.                 *fontSize = -1;
  2760.             }
  2761.             
  2762.             DisposeDialog(dialog);
  2763.             DisposeRoutineDescriptor(otherDialogProc);
  2764.             
  2765.             session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fModalFocus, frame);
  2766.                 // Inform the Arbitrator that we no longer require the Modal focus.
  2767.             
  2768.             session->GetWindowState(ev)->ActivateFrontWindows(ev);
  2769.                 // Hilite the frontmost document window.
  2770.         }
  2771.  
  2772.     SOM_CATCH_ALL
  2773.     SOM_ENDTRY
  2774. }
  2775.  
  2776. //------------------------------------------------------------------------------
  2777. // Method:        DoIdle
  2778. // Origin:        TextEditor
  2779. //------------------------------------------------------------------------------
  2780.  
  2781. SOM_Scope    void
  2782. SOMLINK        TextEditor__DoIdle
  2783.             (
  2784.                 SampleCode_TextEditor*        somSelf,
  2785.                 Environment*                ev,
  2786.                 ODFrame*                    frame
  2787.             )
  2788. {
  2789.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2790.     SOMMethodDebug("TextEditor","DoIdle");
  2791.  
  2792.     SOM_TRY
  2793.     
  2794.         CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
  2795.         ODFacet* facet = frameInfo->GetActiveFacet();
  2796.     
  2797.         if ( facet )
  2798.         {
  2799.             // Focus drawing environment so caret is drawn in the right place.
  2800.             CFocus initiateDrawing(ev, facet);
  2801.                 
  2802.             // Idle Textension.
  2803.             _fTextension->Idle();
  2804.         }
  2805.     
  2806.     SOM_CATCH_ALL
  2807.     SOM_ENDTRY
  2808. }
  2809.  
  2810. //------------------------------------------------------------------------------
  2811. // Method:        DoAboutBox
  2812. // Origin:        TextEditor
  2813. //------------------------------------------------------------------------------
  2814.  
  2815. SOM_Scope    void
  2816. SOMLINK        TextEditor__DoAboutBox
  2817.              (
  2818.                 SampleCode_TextEditor*        somSelf,
  2819.                 Environment*                ev,
  2820.                 ODFrame*                    frame
  2821.             )
  2822. {
  2823.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2824.     SOMMethodDebug("TextEditor","DoAboutBox");
  2825.  
  2826.     SOM_TRY
  2827.         
  2828.         somSelf->DoDialogBox(ev, frame, kAboutDialogID, 0);
  2829.  
  2830.     SOM_CATCH_ALL
  2831.     SOM_ENDTRY
  2832. }
  2833.  
  2834.  
  2835. //------------------------------------------------------------------------------
  2836. // Method:        DoDialogBox
  2837. // Origin:        TextEditor
  2838. //
  2839. // Description:    This method is called by the part when a dialog needs to be
  2840. //                displayed (e.g. the About Box). If a valid error number is passed
  2841. //                in, an error dialog will be displayed.
  2842. //------------------------------------------------------------------------------
  2843.  
  2844. SOM_Scope    void
  2845. SOMLINK        TextEditor__DoDialogBox
  2846.              (
  2847.                 SampleCode_TextEditor*        somSelf,
  2848.                 Environment*                ev,
  2849.                 ODFrame*                    frame,
  2850.                  ODSShort                    dialogID,
  2851.                 ODUShort                    errorNumber
  2852.             )
  2853. {
  2854.     SampleCode_TextEditorData *somThis = SampleCode_TextEditorGetData(somSelf);
  2855.     SOMMethodDebug("TextEditor","DoDialogBox");
  2856.  
  2857.     SOM_TRY
  2858.     
  2859.         ODFrame* focusFrame = frame;
  2860.         ODSession*    session = ODGetSession(ev, somSelf);
  2861.         
  2862.         // If the calling method does not have a frame available to it, we need to
  2863.         // locate a frame to use for requesting the modal focus. Find the first valid
  2864.         // frame in our display frames list.
  2865.         if ( focusFrame == kODNULL )
  2866.         {
  2867.             CListIterator fiter(_fDisplayFrames);
  2868.             for ( CFrameProxy* proxy = (CFrameProxy*) fiter.First();
  2869.                     fiter.IsNotComplete(); proxy = (CFrameProxy*) fiter.Next() )
  2870.             {
  2871.                 if ( proxy->FrameIsLoaded(ev) )
  2872.                     focusFrame = proxy->GetFrame(ev);
  2873.                 if ( focusFrame ) break;
  2874.             }
  2875.         }
  2876.         
  2877.         // Our dialog boxes are modal so we must request the Modal focus to prevent
  2878.         // multiple modal dialogs being displayed simultaneously.
  2879.         
  2880.         if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fModalFocus, focusFrame) )
  2881.         {
  2882.             DialogPtr    dialog;
  2883.             ODSShort    itemHit;
  2884.     
  2885.             // Dim the frontmost document window.
  2886.             session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  2887.                     
  2888.             CUsingLibraryResources res;
  2889.  
  2890.             dialog = GetNewDialog(dialogID, kODNULL, (WindowPtr) -1L);
  2891.             
  2892.             if ( dialog )
  2893.             {
  2894.                 if ( errorNumber > 0 )
  2895.                 {
  2896.                     Handle    iHandle;
  2897.                     Rect    iRect;
  2898.                     short    iType;
  2899.                     Str255    errStr;
  2900.                     
  2901.                     GetIndString(errStr, kErrorStringsID, errorNumber);
  2902.                     GetDialogItem(dialog, kErrStrFieldID, &iType, &iHandle, &iRect);
  2903.                     SetDialogItemText(iHandle, errStr);
  2904.                     
  2905.                     // We don't need the cancel button for an error dialog.
  2906.                     HideDialogItem(dialog, cancel);
  2907.  
  2908.                     SetDialogDefaultItem(dialog, ok);
  2909.                 }
  2910.                 
  2911.                 ShowWindow(dialog);
  2912.                 SetCursor(&ODQDGlobals.arrow);
  2913.                 ModalDialog(kODNULL, &itemHit);
  2914.                 DisposeDialog(dialog);
  2915.             }
  2916.             else
  2917.             {
  2918.                 // Could not load dialog box dialog... something is amiss.
  2919.                 SysBeep(2);
  2920.             }
  2921.             
  2922.             // Hilite the frontmost document window.
  2923.             session->GetWindowState(ev)->ActivateFrontWindows(ev);
  2924.  
  2925.             // Inform the Arbitrator that we no longer require the Modal focus.
  2926.             session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fModalFocus, focusFrame);
  2927.         }
  2928.         else
  2929.         {
  2930.             // If we can't get the modal focus, then another modal dialog is
  2931.             // already being displayed.
  2932.             SysBeep(2);
  2933.         }
  2934.         
  2935.     SOM_CATCH_ALL
  2936.     SOM_ENDTRY
  2937. }
  2938.  
  2939.